@glideidentity/web-client-sdk 5.0.1 → 5.1.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -108
- package/dist/adapters/angular/index.js +1 -0
- package/dist/adapters/angular/phone-auth.service.d.ts +18 -0
- package/dist/adapters/angular/phone-auth.service.js +26 -0
- package/dist/adapters/react/index.js +3 -0
- package/dist/adapters/react/useClient.js +1 -0
- package/dist/adapters/react/usePhoneAuth.js +16 -1
- package/dist/adapters/vanilla/client.js +1 -0
- package/dist/adapters/vanilla/index.js +1 -0
- package/dist/adapters/vanilla/phone-auth.js +31 -0
- package/dist/adapters/vue/index.js +4 -0
- package/dist/adapters/vue/useClient.js +5 -0
- package/dist/adapters/vue/usePhoneAuth.js +20 -1
- package/dist/browser/web-client-sdk.min.js +1 -2
- package/dist/browser.js +6 -0
- package/dist/core/client.js +12 -0
- package/dist/core/logger.js +81 -1
- package/dist/core/phone-auth/api-types.d.ts +1 -4
- package/dist/core/phone-auth/api-types.js +83 -0
- package/dist/core/phone-auth/client.js +374 -38
- package/dist/core/phone-auth/error-utils.js +83 -1
- package/dist/core/phone-auth/index.d.ts +1 -1
- package/dist/core/phone-auth/index.js +2 -2
- package/dist/core/phone-auth/status-types.d.ts +78 -0
- package/dist/core/phone-auth/status-types.js +17 -0
- package/dist/core/phone-auth/strategies/desktop.d.ts +2 -0
- package/dist/core/phone-auth/strategies/desktop.js +136 -13
- package/dist/core/phone-auth/strategies/index.d.ts +4 -0
- package/dist/core/phone-auth/strategies/index.js +4 -0
- package/dist/core/phone-auth/strategies/link.d.ts +2 -0
- package/dist/core/phone-auth/strategies/link.js +97 -13
- package/dist/core/phone-auth/strategies/ts43.d.ts +19 -0
- package/dist/core/phone-auth/strategies/ts43.js +33 -2
- package/dist/core/phone-auth/strategies/types.js +4 -0
- package/dist/core/phone-auth/type-guards.js +131 -0
- package/dist/core/phone-auth/types.d.ts +5 -0
- package/dist/core/phone-auth/types.js +32 -0
- package/dist/core/phone-auth/ui/mobile-debug-console.js +28 -2
- package/dist/core/phone-auth/ui/modal.d.ts +55 -33
- package/dist/core/phone-auth/ui/modal.js +422 -889
- package/dist/core/phone-auth/validation-utils.d.ts +0 -9
- package/dist/core/phone-auth/validation-utils.js +34 -25
- package/dist/core/version.js +2 -1
- package/dist/esm/adapters/angular/index.js +1 -0
- package/dist/esm/adapters/angular/phone-auth.service.d.ts +18 -0
- package/dist/esm/adapters/angular/phone-auth.service.js +26 -0
- package/dist/esm/adapters/react/index.js +3 -0
- package/dist/esm/adapters/react/useClient.js +1 -0
- package/dist/esm/adapters/react/usePhoneAuth.js +16 -1
- package/dist/esm/adapters/vanilla/client.js +1 -0
- package/dist/esm/adapters/vanilla/index.js +1 -0
- package/dist/esm/adapters/vanilla/phone-auth.d.ts +24 -0
- package/dist/esm/adapters/vanilla/phone-auth.js +31 -0
- package/dist/esm/adapters/vue/index.js +4 -0
- package/dist/esm/adapters/vue/useClient.js +5 -0
- package/dist/esm/adapters/vue/usePhoneAuth.js +20 -1
- package/dist/esm/browser.js +6 -0
- package/dist/esm/core/client.d.ts +10 -0
- package/dist/esm/core/client.js +12 -0
- package/dist/esm/core/logger.d.ts +53 -0
- package/dist/esm/core/logger.js +81 -1
- package/dist/esm/core/phone-auth/api-types.d.ts +313 -1
- package/dist/esm/core/phone-auth/api-types.js +83 -0
- package/dist/esm/core/phone-auth/client.d.ts +144 -0
- package/dist/esm/core/phone-auth/client.js +375 -39
- package/dist/esm/core/phone-auth/error-utils.d.ts +29 -0
- package/dist/esm/core/phone-auth/error-utils.js +83 -1
- package/dist/esm/core/phone-auth/index.d.ts +1 -1
- package/dist/esm/core/phone-auth/index.js +4 -2
- package/dist/esm/core/phone-auth/status-types.d.ts +78 -0
- package/dist/esm/core/phone-auth/status-types.js +17 -0
- package/dist/esm/core/phone-auth/strategies/desktop.d.ts +65 -0
- package/dist/esm/core/phone-auth/strategies/desktop.js +136 -13
- package/dist/esm/core/phone-auth/strategies/index.d.ts +4 -0
- package/dist/esm/core/phone-auth/strategies/index.js +4 -0
- package/dist/esm/core/phone-auth/strategies/link.d.ts +50 -0
- package/dist/esm/core/phone-auth/strategies/link.js +97 -13
- package/dist/esm/core/phone-auth/strategies/ts43.d.ts +19 -0
- package/dist/esm/core/phone-auth/strategies/ts43.js +33 -2
- package/dist/esm/core/phone-auth/strategies/types.d.ts +13 -0
- package/dist/esm/core/phone-auth/strategies/types.js +4 -0
- package/dist/esm/core/phone-auth/type-guards.d.ts +128 -0
- package/dist/esm/core/phone-auth/type-guards.js +131 -0
- package/dist/esm/core/phone-auth/types.d.ts +113 -0
- package/dist/esm/core/phone-auth/types.js +32 -0
- package/dist/esm/core/phone-auth/ui/mobile-debug-console.d.ts +4 -0
- package/dist/esm/core/phone-auth/ui/mobile-debug-console.js +28 -2
- package/dist/esm/core/phone-auth/ui/modal.d.ts +68 -27
- package/dist/esm/core/phone-auth/ui/modal.js +422 -889
- package/dist/esm/core/phone-auth/validation-utils.d.ts +26 -4
- package/dist/esm/core/phone-auth/validation-utils.js +34 -24
- package/dist/esm/core/types.d.ts +35 -0
- package/dist/esm/core/version.js +2 -1
- package/dist/esm/index.js +9 -1
- package/dist/index.js +7 -0
- package/package.json +1 -1
- package/dist/browser/web-client-sdk.min.js.LICENSE.txt +0 -1
package/README.md
CHANGED
|
@@ -14,19 +14,9 @@ The official web SDK for integrating Glide's carrier-grade phone verification in
|
|
|
14
14
|
- 🛡️ **Type Safe**: Full TypeScript support with type guards and IntelliSense
|
|
15
15
|
- 🎯 **Developer Friendly**: Clear error messages and browser compatibility checks
|
|
16
16
|
|
|
17
|
-
## What's New in
|
|
18
|
-
|
|
19
|
-
###
|
|
20
|
-
- **Glass Morphism Design**: Modern frosted glass aesthetic with blur effects
|
|
21
|
-
- **Multiple View Modes**: Choose between `toggle`, `dual`, or `pre-step` layouts
|
|
22
|
-
- **Theme Support**: `dark`, `light`, or `auto` (follows system preference)
|
|
23
|
-
- **OS Icons**: Apple and Android icons in toggle and dual mode
|
|
24
|
-
- **Smooth Animations**: Fade-in/scale transitions and sliding toggle switch
|
|
25
|
-
- **Help Interaction**: Expandable help panel with smooth slide-out animation
|
|
26
|
-
- **Body Scroll Lock**: Background page no longer scrolls when modal is open
|
|
27
|
-
- **Improved Accessibility**: Keyboard support (Escape to close), proper ARIA labels
|
|
28
|
-
|
|
29
|
-
### 🎉 Enhanced Control & Better DX (v4.4)
|
|
17
|
+
## What's New in v4.4
|
|
18
|
+
|
|
19
|
+
### 🎉 Enhanced Control & Better DX
|
|
30
20
|
- **Extended Mode**: More control with `executionMode: 'extended'` for granular authentication flow
|
|
31
21
|
- **Prevent Default UI**: Use `preventDefaultUI: true` to disable all SDK modals
|
|
32
22
|
- **Type Guards**: Helper functions for type-safe result handling
|
|
@@ -41,7 +31,6 @@ The official web SDK for integrating Glide's carrier-grade phone verification in
|
|
|
41
31
|
- [Installation](#installation)
|
|
42
32
|
- [Development](#development)
|
|
43
33
|
- [Quick Start](#quick-start)
|
|
44
|
-
- [Modal Customization](#modal-customization)
|
|
45
34
|
- [Extended Mode - Advanced Control](#extended-mode---advanced-control)
|
|
46
35
|
- [Authentication Strategies](#authentication-strategies)
|
|
47
36
|
- [Framework Examples](#framework-examples)
|
|
@@ -157,84 +146,6 @@ function PhoneVerification() {
|
|
|
157
146
|
}
|
|
158
147
|
```
|
|
159
148
|
|
|
160
|
-
## Modal Customization
|
|
161
|
-
|
|
162
|
-
The SDK provides a built-in modal for QR code display with extensive customization options.
|
|
163
|
-
|
|
164
|
-
### View Modes
|
|
165
|
-
|
|
166
|
-
Choose how the QR code is displayed to users:
|
|
167
|
-
|
|
168
|
-
| Mode | Description | Best For |
|
|
169
|
-
|------|-------------|----------|
|
|
170
|
-
| `toggle` | Single QR with iOS/Android sliding toggle switch | Default, clean UI |
|
|
171
|
-
| `dual` | Side-by-side QR codes for both platforms | When users might not know their OS |
|
|
172
|
-
| `pre-step` | OS selection screen before showing QR | Guided experience |
|
|
173
|
-
|
|
174
|
-
```javascript
|
|
175
|
-
const credential = await phoneAuth.invokeSecurePrompt(prepareResult, {
|
|
176
|
-
modalOptions: {
|
|
177
|
-
viewMode: 'dual' // 'toggle' | 'dual' | 'pre-step'
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### Theme Options
|
|
183
|
-
|
|
184
|
-
Control the modal's appearance:
|
|
185
|
-
|
|
186
|
-
```javascript
|
|
187
|
-
const credential = await phoneAuth.invokeSecurePrompt(prepareResult, {
|
|
188
|
-
modalOptions: {
|
|
189
|
-
theme: 'auto', // 'dark' | 'light' | 'auto' (follows system preference)
|
|
190
|
-
title: 'Scan to Verify',
|
|
191
|
-
showCloseButton: true,
|
|
192
|
-
closeOnBackdrop: true,
|
|
193
|
-
closeOnEscape: true
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### Full Modal Options
|
|
199
|
-
|
|
200
|
-
```typescript
|
|
201
|
-
modalOptions: {
|
|
202
|
-
// View mode
|
|
203
|
-
viewMode?: 'toggle' | 'dual' | 'pre-step'; // Default: 'toggle'
|
|
204
|
-
|
|
205
|
-
// Theme
|
|
206
|
-
theme?: 'dark' | 'light' | 'auto'; // Default: 'auto'
|
|
207
|
-
|
|
208
|
-
// Content
|
|
209
|
-
title?: string; // Modal title
|
|
210
|
-
|
|
211
|
-
// Behavior
|
|
212
|
-
showCloseButton?: boolean; // Show X button (default: true)
|
|
213
|
-
closeOnBackdrop?: boolean; // Close when clicking outside (default: true)
|
|
214
|
-
closeOnEscape?: boolean; // Close on Escape key (default: true)
|
|
215
|
-
|
|
216
|
-
// Styling
|
|
217
|
-
className?: string; // Custom CSS class for modal
|
|
218
|
-
}
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
### View Mode Examples
|
|
222
|
-
|
|
223
|
-
**Toggle Mode** (default) - Clean single QR with platform switcher:
|
|
224
|
-
```javascript
|
|
225
|
-
modalOptions: { viewMode: 'toggle' }
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
**Dual Mode** - Both QR codes visible at once:
|
|
229
|
-
```javascript
|
|
230
|
-
modalOptions: { viewMode: 'dual' }
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
**Pre-step Mode** - User selects platform first:
|
|
234
|
-
```javascript
|
|
235
|
-
modalOptions: { viewMode: 'pre-step' }
|
|
236
|
-
```
|
|
237
|
-
|
|
238
149
|
## Extended Mode - Advanced Control
|
|
239
150
|
|
|
240
151
|
The SDK supports an **Extended Mode** that provides granular control over the authentication flow. This mode returns an `ExtendedResponse` object with additional methods and data for custom implementations.
|
|
@@ -665,22 +576,11 @@ interface InvokeOptions {
|
|
|
665
576
|
|
|
666
577
|
// UI customization (when preventDefaultUI is false)
|
|
667
578
|
modalOptions?: {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
// Content
|
|
675
|
-
title?: string; // Modal title text
|
|
676
|
-
|
|
677
|
-
// Behavior
|
|
678
|
-
showCloseButton?: boolean; // Show X button (default: true)
|
|
679
|
-
closeOnBackdrop?: boolean; // Close on backdrop click (default: true)
|
|
680
|
-
closeOnEscape?: boolean; // Close on Escape key (default: true)
|
|
681
|
-
|
|
682
|
-
// Styling
|
|
683
|
-
className?: string; // Custom CSS class
|
|
579
|
+
className?: string;
|
|
580
|
+
title?: string;
|
|
581
|
+
description?: string;
|
|
582
|
+
buttonText?: string;
|
|
583
|
+
showCloseButton?: boolean;
|
|
684
584
|
};
|
|
685
585
|
|
|
686
586
|
// Callbacks
|
|
@@ -5,6 +5,7 @@ var client_service_1 = require("./client.service");
|
|
|
5
5
|
Object.defineProperty(exports, "ClientService", { enumerable: true, get: function () { return client_service_1.ClientService; } });
|
|
6
6
|
var phone_auth_service_1 = require("./phone-auth.service");
|
|
7
7
|
Object.defineProperty(exports, "PhoneAuthService", { enumerable: true, get: function () { return phone_auth_service_1.PhoneAuthService; } });
|
|
8
|
+
// Export error utilities
|
|
8
9
|
var phone_auth_1 = require("../../core/phone-auth");
|
|
9
10
|
Object.defineProperty(exports, "PhoneAuthErrorCode", { enumerable: true, get: function () { return phone_auth_1.PhoneAuthErrorCode; } });
|
|
10
11
|
Object.defineProperty(exports, "isPhoneAuthError", { enumerable: true, get: function () { return phone_auth_1.isPhoneAuthError; } });
|
|
@@ -11,10 +11,28 @@ export declare class PhoneAuthService {
|
|
|
11
11
|
result$: Observable<PhoneAuthResult | null>;
|
|
12
12
|
currentStep$: Observable<AuthStep>;
|
|
13
13
|
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Configure the phone auth client
|
|
16
|
+
*/
|
|
14
17
|
configure(config: AuthConfig): void;
|
|
18
|
+
/**
|
|
19
|
+
* Check if browser supports secure phone authentication
|
|
20
|
+
*/
|
|
15
21
|
isSupported(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Verify phone number
|
|
24
|
+
*/
|
|
16
25
|
verify(options: PhoneAuthOptions): Promise<PhoneAuthResult>;
|
|
26
|
+
/**
|
|
27
|
+
* Get phone number
|
|
28
|
+
*/
|
|
17
29
|
getPhoneNumber(options?: Omit<PhoneAuthOptions, 'use_case' | 'phone_number'>): Promise<PhoneAuthResult>;
|
|
30
|
+
/**
|
|
31
|
+
* Verify specific phone number
|
|
32
|
+
*/
|
|
18
33
|
verifyPhoneNumber(phoneNumber: string, options?: Omit<PhoneAuthOptions, 'use_case' | 'phone_number'>): Promise<PhoneAuthResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Reset state
|
|
36
|
+
*/
|
|
19
37
|
reset(): void;
|
|
20
38
|
}
|
|
@@ -24,22 +24,33 @@ const phone_auth_1 = require("../../core/phone-auth");
|
|
|
24
24
|
const rxjs_1 = require("rxjs");
|
|
25
25
|
let PhoneAuthService = class PhoneAuthService {
|
|
26
26
|
constructor() {
|
|
27
|
+
// State subjects
|
|
27
28
|
this.isLoadingSubject = new rxjs_1.BehaviorSubject(false);
|
|
28
29
|
this.errorSubject = new rxjs_1.BehaviorSubject(null);
|
|
29
30
|
this.resultSubject = new rxjs_1.BehaviorSubject(null);
|
|
30
31
|
this.currentStepSubject = new rxjs_1.BehaviorSubject('idle');
|
|
32
|
+
// Public observables
|
|
31
33
|
this.isLoading$ = this.isLoadingSubject.asObservable();
|
|
32
34
|
this.error$ = this.errorSubject.asObservable();
|
|
33
35
|
this.result$ = this.resultSubject.asObservable();
|
|
34
36
|
this.currentStep$ = this.currentStepSubject.asObservable();
|
|
35
37
|
this.client = new phone_auth_1.PhoneAuthClient();
|
|
36
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Configure the phone auth client
|
|
41
|
+
*/
|
|
37
42
|
configure(config) {
|
|
38
43
|
this.client = new phone_auth_1.PhoneAuthClient(config);
|
|
39
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Check if browser supports secure phone authentication
|
|
47
|
+
*/
|
|
40
48
|
isSupported() {
|
|
41
49
|
return this.client.isSupported();
|
|
42
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Verify phone number
|
|
53
|
+
*/
|
|
43
54
|
verify(options) {
|
|
44
55
|
return __awaiter(this, void 0, void 0, function* () {
|
|
45
56
|
this.isLoadingSubject.next(true);
|
|
@@ -47,14 +58,19 @@ let PhoneAuthService = class PhoneAuthService {
|
|
|
47
58
|
this.resultSubject.next(null);
|
|
48
59
|
this.currentStepSubject.next('requesting');
|
|
49
60
|
try {
|
|
61
|
+
// Step 1: Prepare request
|
|
50
62
|
const preparedRequest = yield this.client.preparePhoneRequest(options);
|
|
63
|
+
// Step 2: Show authenticating state
|
|
51
64
|
this.currentStepSubject.next('authenticating');
|
|
52
65
|
const credentialResponse = yield this.client.invokeSecurePrompt(preparedRequest);
|
|
66
|
+
// Step 3: Process response through appropriate endpoint
|
|
53
67
|
this.currentStepSubject.next('processing');
|
|
68
|
+
// Cast to credential type - adapters never use headless mode
|
|
54
69
|
const credential = credentialResponse;
|
|
55
70
|
const processedResult = options.use_case === 'GetPhoneNumber'
|
|
56
71
|
? yield this.client.getPhoneNumber(credential, preparedRequest.session)
|
|
57
72
|
: yield this.client.verifyPhoneNumber(credential, preparedRequest.session);
|
|
73
|
+
// Create final result
|
|
58
74
|
const isVerifyResponse = 'verified' in processedResult;
|
|
59
75
|
const result = processedResult;
|
|
60
76
|
this.resultSubject.next(result);
|
|
@@ -62,6 +78,7 @@ let PhoneAuthService = class PhoneAuthService {
|
|
|
62
78
|
return result;
|
|
63
79
|
}
|
|
64
80
|
catch (error) {
|
|
81
|
+
// Enhance error with context
|
|
65
82
|
const authError = error;
|
|
66
83
|
const enhancedError = Object.assign(Object.assign({}, authError), { context: authError.context || {
|
|
67
84
|
useCase: options.use_case,
|
|
@@ -78,16 +95,25 @@ let PhoneAuthService = class PhoneAuthService {
|
|
|
78
95
|
}
|
|
79
96
|
});
|
|
80
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Get phone number
|
|
100
|
+
*/
|
|
81
101
|
getPhoneNumber(options) {
|
|
82
102
|
return __awaiter(this, void 0, void 0, function* () {
|
|
83
103
|
return this.verify(Object.assign({ use_case: 'GetPhoneNumber' }, options));
|
|
84
104
|
});
|
|
85
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Verify specific phone number
|
|
108
|
+
*/
|
|
86
109
|
verifyPhoneNumber(phoneNumber, options) {
|
|
87
110
|
return __awaiter(this, void 0, void 0, function* () {
|
|
88
111
|
return this.verify(Object.assign({ use_case: 'VerifyPhoneNumber', phone_number: phoneNumber }, options));
|
|
89
112
|
});
|
|
90
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Reset state
|
|
116
|
+
*/
|
|
91
117
|
reset() {
|
|
92
118
|
this.isLoadingSubject.next(false);
|
|
93
119
|
this.errorSubject.next(null);
|
|
@@ -5,6 +5,7 @@ var usePhoneAuth_1 = require("./usePhoneAuth");
|
|
|
5
5
|
Object.defineProperty(exports, "usePhoneAuth", { enumerable: true, get: function () { return usePhoneAuth_1.usePhoneAuth; } });
|
|
6
6
|
var useClient_1 = require("./useClient");
|
|
7
7
|
Object.defineProperty(exports, "useClient", { enumerable: true, get: function () { return useClient_1.useClient; } });
|
|
8
|
+
// Export error utilities
|
|
8
9
|
var phone_auth_1 = require("../../core/phone-auth");
|
|
9
10
|
Object.defineProperty(exports, "PhoneAuthErrorCode", { enumerable: true, get: function () { return phone_auth_1.PhoneAuthErrorCode; } });
|
|
10
11
|
Object.defineProperty(exports, "isPhoneAuthError", { enumerable: true, get: function () { return phone_auth_1.isPhoneAuthError; } });
|
|
@@ -15,11 +16,13 @@ Object.defineProperty(exports, "getRetryDelay", { enumerable: true, get: functio
|
|
|
15
16
|
Object.defineProperty(exports, "isRetryableError", { enumerable: true, get: function () { return phone_auth_1.isRetryableError; } });
|
|
16
17
|
Object.defineProperty(exports, "serializeError", { enumerable: true, get: function () { return phone_auth_1.serializeError; } });
|
|
17
18
|
Object.defineProperty(exports, "createErrorBreadcrumb", { enumerable: true, get: function () { return phone_auth_1.createErrorBreadcrumb; } });
|
|
19
|
+
// Export constants for use case and strategy
|
|
18
20
|
var types_1 = require("../../core/phone-auth/types");
|
|
19
21
|
Object.defineProperty(exports, "UseCase", { enumerable: true, get: function () { return types_1.USE_CASE; } });
|
|
20
22
|
Object.defineProperty(exports, "AuthenticationStrategy", { enumerable: true, get: function () { return types_1.AUTHENTICATION_STRATEGY; } });
|
|
21
23
|
Object.defineProperty(exports, "BrowserError", { enumerable: true, get: function () { return types_1.BrowserError; } });
|
|
22
24
|
Object.defineProperty(exports, "BrowserErrorCode", { enumerable: true, get: function () { return types_1.BrowserErrorCode; } });
|
|
23
25
|
Object.defineProperty(exports, "BrowserName", { enumerable: true, get: function () { return types_1.BrowserName; } });
|
|
26
|
+
// Export the PhoneAuthClient class for direct use
|
|
24
27
|
var phone_auth_2 = require("../../core/phone-auth");
|
|
25
28
|
Object.defineProperty(exports, "PhoneAuthClient", { enumerable: true, get: function () { return phone_auth_2.PhoneAuthClient; } });
|
|
@@ -31,6 +31,7 @@ function useClient(config) {
|
|
|
31
31
|
};
|
|
32
32
|
}, []);
|
|
33
33
|
const authenticate = (authUrl, options) => __awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
// Legacy authentication removed - use setToken directly
|
|
34
35
|
const error = new Error('authenticate method is deprecated. Use client.setToken() directly.');
|
|
35
36
|
setError(error);
|
|
36
37
|
setLoading(false);
|
|
@@ -18,8 +18,13 @@ function usePhoneAuth(config = {}) {
|
|
|
18
18
|
const [result, setResult] = (0, react_1.useState)(null);
|
|
19
19
|
const [currentStep, setCurrentStep] = (0, react_1.useState)('idle');
|
|
20
20
|
const lastRequestRef = (0, react_1.useRef)(null);
|
|
21
|
-
|
|
21
|
+
// Create client instance with callbacks
|
|
22
|
+
const client = (0, react_1.useMemo)(() => new phone_auth_1.PhoneAuthClient(Object.assign(Object.assign({}, config), {
|
|
23
|
+
// Pass through callbacks if provided
|
|
24
|
+
onCrossDeviceDetected: config.onCrossDeviceDetected, onRetryAttempt: config.onRetryAttempt })), [JSON.stringify(config)]);
|
|
25
|
+
// Check browser support
|
|
22
26
|
const isSupported = (0, react_1.useMemo)(() => client.isSupported(), [client]);
|
|
27
|
+
// Verify method with silent retry support
|
|
23
28
|
const verify = (0, react_1.useCallback)((options) => __awaiter(this, void 0, void 0, function* () {
|
|
24
29
|
setIsLoading(true);
|
|
25
30
|
setError(null);
|
|
@@ -27,12 +32,14 @@ function usePhoneAuth(config = {}) {
|
|
|
27
32
|
setCurrentStep('requesting');
|
|
28
33
|
lastRequestRef.current = options;
|
|
29
34
|
try {
|
|
35
|
+
// Use the client's verify method which includes retry logic
|
|
30
36
|
const verificationResult = yield client.verify(options);
|
|
31
37
|
setResult(verificationResult);
|
|
32
38
|
setCurrentStep('complete');
|
|
33
39
|
return verificationResult;
|
|
34
40
|
}
|
|
35
41
|
catch (err) {
|
|
42
|
+
// Error is only set after all retries are exhausted
|
|
36
43
|
const authError = err;
|
|
37
44
|
setError(authError);
|
|
38
45
|
setCurrentStep('idle');
|
|
@@ -42,39 +49,47 @@ function usePhoneAuth(config = {}) {
|
|
|
42
49
|
setIsLoading(false);
|
|
43
50
|
}
|
|
44
51
|
}), [client]);
|
|
52
|
+
// Manual retry method
|
|
45
53
|
const retryLastRequest = (0, react_1.useCallback)(() => __awaiter(this, void 0, void 0, function* () {
|
|
46
54
|
if (!lastRequestRef.current) {
|
|
47
55
|
throw new Error('No previous request to retry');
|
|
48
56
|
}
|
|
49
57
|
return verify(lastRequestRef.current);
|
|
50
58
|
}), [verify]);
|
|
59
|
+
// Convenience methods
|
|
51
60
|
const getPhoneNumber = (0, react_1.useCallback)((options) => verify(Object.assign({ use_case: 'GetPhoneNumber' }, options)), [verify]);
|
|
52
61
|
const verifyPhoneNumber = (0, react_1.useCallback)((phoneNumber, options) => verify(Object.assign({ use_case: 'VerifyPhoneNumber', phone_number: phoneNumber }, options)), [verify]);
|
|
62
|
+
// Reset state
|
|
53
63
|
const reset = (0, react_1.useCallback)(() => {
|
|
54
64
|
setIsLoading(false);
|
|
55
65
|
setError(null);
|
|
56
66
|
setResult(null);
|
|
57
67
|
setCurrentStep('idle');
|
|
58
68
|
}, []);
|
|
69
|
+
// Expose granular methods directly from client for better discoverability
|
|
59
70
|
const preparePhoneRequest = (0, react_1.useCallback)((options) => client.preparePhoneRequest(options), [client]);
|
|
60
71
|
const invokeSecurePrompt = (0, react_1.useCallback)((prepareResponse) => client.invokeSecurePrompt(prepareResponse), [client]);
|
|
61
72
|
const getPhoneNumberCredential = (0, react_1.useCallback)((credentialResponse, session) => client.getPhoneNumber(credentialResponse, session), [client]);
|
|
62
73
|
const verifyPhoneNumberCredential = (0, react_1.useCallback)((credentialResponse, session) => client.verifyPhoneNumber(credentialResponse, session), [client]);
|
|
63
74
|
return {
|
|
75
|
+
// State
|
|
64
76
|
isLoading,
|
|
65
77
|
error,
|
|
66
78
|
result,
|
|
67
79
|
currentStep,
|
|
68
80
|
isSupported,
|
|
81
|
+
// High-level methods
|
|
69
82
|
verify,
|
|
70
83
|
getPhoneNumber,
|
|
71
84
|
verifyPhoneNumber,
|
|
72
85
|
retryLastRequest,
|
|
73
86
|
reset,
|
|
87
|
+
// Granular methods (directly exposed for better discoverability)
|
|
74
88
|
preparePhoneRequest,
|
|
75
89
|
invokeSecurePrompt,
|
|
76
90
|
getPhoneNumberCredential,
|
|
77
91
|
verifyPhoneNumberCredential,
|
|
92
|
+
// Client instance (still available for advanced usage)
|
|
78
93
|
client
|
|
79
94
|
};
|
|
80
95
|
}
|
|
@@ -17,6 +17,7 @@ class VanillaClient {
|
|
|
17
17
|
}
|
|
18
18
|
authenticate(authUrl, options) {
|
|
19
19
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
// Legacy authentication removed - use setToken directly
|
|
20
21
|
throw new Error('authenticate method is deprecated. Use client.setToken() directly.');
|
|
21
22
|
});
|
|
22
23
|
}
|
|
@@ -5,6 +5,7 @@ var client_1 = require("./client");
|
|
|
5
5
|
Object.defineProperty(exports, "ClientManager", { enumerable: true, get: function () { return client_1.VanillaClient; } });
|
|
6
6
|
var phone_auth_1 = require("./phone-auth");
|
|
7
7
|
Object.defineProperty(exports, "PhoneAuthManager", { enumerable: true, get: function () { return phone_auth_1.PhoneAuthManager; } });
|
|
8
|
+
// Export error utilities
|
|
8
9
|
var phone_auth_2 = require("../../core/phone-auth");
|
|
9
10
|
Object.defineProperty(exports, "PhoneAuthErrorCode", { enumerable: true, get: function () { return phone_auth_2.PhoneAuthErrorCode; } });
|
|
10
11
|
Object.defineProperty(exports, "isPhoneAuthError", { enumerable: true, get: function () { return phone_auth_2.isPhoneAuthError; } });
|
|
@@ -23,11 +23,18 @@ class PhoneAuthManager {
|
|
|
23
23
|
isSupported: this.client.isSupported()
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Get current state
|
|
28
|
+
*/
|
|
26
29
|
getState() {
|
|
27
30
|
return Object.assign({}, this.state);
|
|
28
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Subscribe to state changes
|
|
34
|
+
*/
|
|
29
35
|
subscribe(listener) {
|
|
30
36
|
this.listeners.push(listener);
|
|
37
|
+
// Return unsubscribe function
|
|
31
38
|
return () => {
|
|
32
39
|
const index = this.listeners.indexOf(listener);
|
|
33
40
|
if (index !== -1) {
|
|
@@ -35,10 +42,16 @@ class PhoneAuthManager {
|
|
|
35
42
|
}
|
|
36
43
|
};
|
|
37
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Update state and notify listeners
|
|
47
|
+
*/
|
|
38
48
|
updateState(updates) {
|
|
39
49
|
this.state = Object.assign(Object.assign({}, this.state), updates);
|
|
40
50
|
this.listeners.forEach(listener => listener(this.getState()));
|
|
41
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Verify phone number
|
|
54
|
+
*/
|
|
42
55
|
verify(options) {
|
|
43
56
|
return __awaiter(this, void 0, void 0, function* () {
|
|
44
57
|
this.updateState({
|
|
@@ -48,14 +61,19 @@ class PhoneAuthManager {
|
|
|
48
61
|
currentStep: 'requesting'
|
|
49
62
|
});
|
|
50
63
|
try {
|
|
64
|
+
// Step 1: Prepare request
|
|
51
65
|
const preparedRequest = yield this.client.preparePhoneRequest(options);
|
|
66
|
+
// Step 2: Show authenticating state
|
|
52
67
|
this.updateState({ currentStep: 'authenticating' });
|
|
53
68
|
const credentialResponse = yield this.client.invokeSecurePrompt(preparedRequest);
|
|
69
|
+
// Step 3: Process response through appropriate endpoint
|
|
54
70
|
this.updateState({ currentStep: 'processing' });
|
|
71
|
+
// Cast to credential type - adapters never use headless mode
|
|
55
72
|
const credential = credentialResponse;
|
|
56
73
|
const processedResult = options.use_case === 'GetPhoneNumber'
|
|
57
74
|
? yield this.client.getPhoneNumber(credential, preparedRequest.session)
|
|
58
75
|
: yield this.client.verifyPhoneNumber(credential, preparedRequest.session);
|
|
76
|
+
// Create final result
|
|
59
77
|
const isVerifyResponse = 'verified' in processedResult;
|
|
60
78
|
const result = processedResult;
|
|
61
79
|
this.updateState({
|
|
@@ -66,6 +84,7 @@ class PhoneAuthManager {
|
|
|
66
84
|
return result;
|
|
67
85
|
}
|
|
68
86
|
catch (error) {
|
|
87
|
+
// Enhance error with context
|
|
69
88
|
const authError = error;
|
|
70
89
|
const enhancedError = Object.assign(Object.assign({}, authError), { context: authError.context || {
|
|
71
90
|
useCase: options.use_case,
|
|
@@ -82,16 +101,25 @@ class PhoneAuthManager {
|
|
|
82
101
|
}
|
|
83
102
|
});
|
|
84
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Get phone number
|
|
106
|
+
*/
|
|
85
107
|
getPhoneNumber(options) {
|
|
86
108
|
return __awaiter(this, void 0, void 0, function* () {
|
|
87
109
|
return this.verify(Object.assign({ use_case: 'GetPhoneNumber' }, options));
|
|
88
110
|
});
|
|
89
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Verify specific phone number
|
|
114
|
+
*/
|
|
90
115
|
verifyPhoneNumber(phoneNumber, options) {
|
|
91
116
|
return __awaiter(this, void 0, void 0, function* () {
|
|
92
117
|
return this.verify(Object.assign({ use_case: 'VerifyPhoneNumber', phone_number: phoneNumber }, options));
|
|
93
118
|
});
|
|
94
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Reset state
|
|
122
|
+
*/
|
|
95
123
|
reset() {
|
|
96
124
|
this.updateState({
|
|
97
125
|
isLoading: false,
|
|
@@ -100,6 +128,9 @@ class PhoneAuthManager {
|
|
|
100
128
|
currentStep: 'idle'
|
|
101
129
|
});
|
|
102
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Check if browser supports secure phone authentication
|
|
133
|
+
*/
|
|
103
134
|
isSupported() {
|
|
104
135
|
return this.state.isSupported;
|
|
105
136
|
}
|
|
@@ -9,6 +9,8 @@ var client_1 = require("../../core/client");
|
|
|
9
9
|
Object.defineProperty(exports, "SDKClient", { enumerable: true, get: function () { return client_1.SDKClient; } });
|
|
10
10
|
var phone_auth_1 = require("../../core/phone-auth");
|
|
11
11
|
Object.defineProperty(exports, "PhoneAuthClient", { enumerable: true, get: function () { return phone_auth_1.PhoneAuthClient; } });
|
|
12
|
+
// API response types are already exported via core/phone-auth/types
|
|
13
|
+
// Export error utilities
|
|
12
14
|
var phone_auth_2 = require("../../core/phone-auth");
|
|
13
15
|
Object.defineProperty(exports, "PhoneAuthErrorCode", { enumerable: true, get: function () { return phone_auth_2.PhoneAuthErrorCode; } });
|
|
14
16
|
Object.defineProperty(exports, "isPhoneAuthError", { enumerable: true, get: function () { return phone_auth_2.isPhoneAuthError; } });
|
|
@@ -19,12 +21,14 @@ Object.defineProperty(exports, "getRetryDelay", { enumerable: true, get: functio
|
|
|
19
21
|
Object.defineProperty(exports, "isRetryableError", { enumerable: true, get: function () { return phone_auth_2.isRetryableError; } });
|
|
20
22
|
Object.defineProperty(exports, "serializeError", { enumerable: true, get: function () { return phone_auth_2.serializeError; } });
|
|
21
23
|
Object.defineProperty(exports, "createErrorBreadcrumb", { enumerable: true, get: function () { return phone_auth_2.createErrorBreadcrumb; } });
|
|
24
|
+
// Export constants for use case and strategy
|
|
22
25
|
var types_1 = require("../../core/phone-auth/types");
|
|
23
26
|
Object.defineProperty(exports, "UseCase", { enumerable: true, get: function () { return types_1.USE_CASE; } });
|
|
24
27
|
Object.defineProperty(exports, "AuthenticationStrategy", { enumerable: true, get: function () { return types_1.AUTHENTICATION_STRATEGY; } });
|
|
25
28
|
Object.defineProperty(exports, "BrowserError", { enumerable: true, get: function () { return types_1.BrowserError; } });
|
|
26
29
|
Object.defineProperty(exports, "BrowserErrorCode", { enumerable: true, get: function () { return types_1.BrowserErrorCode; } });
|
|
27
30
|
Object.defineProperty(exports, "BrowserName", { enumerable: true, get: function () { return types_1.BrowserName; } });
|
|
31
|
+
// Export API constants from api-types
|
|
28
32
|
var api_types_1 = require("../../core/phone-auth/api-types");
|
|
29
33
|
Object.defineProperty(exports, "USE_CASE", { enumerable: true, get: function () { return api_types_1.USE_CASE; } });
|
|
30
34
|
Object.defineProperty(exports, "ERROR_CODE", { enumerable: true, get: function () { return api_types_1.ERROR_CODE; } });
|
|
@@ -44,14 +44,17 @@ function useClient(config) {
|
|
|
44
44
|
const authenticate = (authUrl) => __awaiter(this, void 0, void 0, function* () {
|
|
45
45
|
loading.value = true;
|
|
46
46
|
error.value = null;
|
|
47
|
+
// Clean up previous authentication if exists
|
|
47
48
|
if (cleanup) {
|
|
48
49
|
cleanup();
|
|
49
50
|
cleanup = null;
|
|
50
51
|
}
|
|
52
|
+
// Legacy authentication removed - use setToken directly
|
|
51
53
|
error.value = new Error('authenticate method is deprecated. Use client.setToken() directly.');
|
|
52
54
|
loading.value = false;
|
|
53
55
|
throw error.value;
|
|
54
56
|
});
|
|
57
|
+
// Cleanup on component unmount
|
|
55
58
|
(0, vue_1.onUnmounted)(() => {
|
|
56
59
|
if (cleanup) {
|
|
57
60
|
cleanup();
|
|
@@ -104,6 +107,7 @@ function useClient(config) {
|
|
|
104
107
|
loading.value = false;
|
|
105
108
|
}
|
|
106
109
|
});
|
|
110
|
+
// Low-level methods for advanced control
|
|
107
111
|
const preparePhoneRequest = (options) => __awaiter(this, void 0, void 0, function* () {
|
|
108
112
|
return client.value.phoneAuth.preparePhoneRequest(options);
|
|
109
113
|
});
|
|
@@ -117,6 +121,7 @@ function useClient(config) {
|
|
|
117
121
|
isSupported,
|
|
118
122
|
getPhoneNumber,
|
|
119
123
|
verifyPhoneNumber,
|
|
124
|
+
// Low-level API for advanced usage
|
|
120
125
|
preparePhoneRequest,
|
|
121
126
|
invokeSecurePrompt
|
|
122
127
|
};
|
|
@@ -13,31 +13,43 @@ exports.usePhoneAuth = usePhoneAuth;
|
|
|
13
13
|
const vue_1 = require("vue");
|
|
14
14
|
const phone_auth_1 = require("../../core/phone-auth");
|
|
15
15
|
function usePhoneAuth(config = {}) {
|
|
16
|
+
// State management
|
|
16
17
|
const isLoading = (0, vue_1.ref)(false);
|
|
17
18
|
const error = (0, vue_1.ref)(null);
|
|
18
19
|
const result = (0, vue_1.ref)(null);
|
|
19
20
|
const currentStep = (0, vue_1.ref)('idle');
|
|
20
|
-
|
|
21
|
+
// Create client instance with callbacks
|
|
22
|
+
const client = new phone_auth_1.PhoneAuthClient(Object.assign(Object.assign({}, config), {
|
|
23
|
+
// Callbacks are now properly typed through AuthConfig
|
|
24
|
+
onCrossDeviceDetected: config.onCrossDeviceDetected, onRetryAttempt: config.onRetryAttempt }));
|
|
25
|
+
// Check browser support
|
|
21
26
|
const isSupported = (0, vue_1.computed)(() => client.isSupported());
|
|
27
|
+
// Verify method - internal wrapper that converts to API format
|
|
22
28
|
const verify = (options) => __awaiter(this, void 0, void 0, function* () {
|
|
23
29
|
isLoading.value = true;
|
|
24
30
|
error.value = null;
|
|
25
31
|
result.value = null;
|
|
26
32
|
currentStep.value = 'requesting';
|
|
27
33
|
try {
|
|
34
|
+
// Step 1: Prepare the request
|
|
28
35
|
const preparedRequest = yield client.preparePhoneRequest(options);
|
|
36
|
+
// Step 2: User authentication
|
|
29
37
|
currentStep.value = 'authenticating';
|
|
30
38
|
const credentialResponse = yield client.invokeSecurePrompt(preparedRequest);
|
|
39
|
+
// Step 3: Process the response through appropriate endpoint
|
|
31
40
|
currentStep.value = 'processing';
|
|
41
|
+
// Cast to credential type - adapters never use headless mode
|
|
32
42
|
const credential = credentialResponse;
|
|
33
43
|
const verificationResult = options.use_case === 'GetPhoneNumber'
|
|
34
44
|
? yield client.getPhoneNumber(credential, preparedRequest.session)
|
|
35
45
|
: yield client.verifyPhoneNumber(credential, preparedRequest.session);
|
|
46
|
+
// Use the result directly - it's already the correct type
|
|
36
47
|
result.value = verificationResult;
|
|
37
48
|
currentStep.value = 'complete';
|
|
38
49
|
return result.value;
|
|
39
50
|
}
|
|
40
51
|
catch (err) {
|
|
52
|
+
// Enhance error with context if it's an AuthError
|
|
41
53
|
const authError = err;
|
|
42
54
|
const enhancedError = Object.assign(Object.assign({}, authError), { context: authError.context || {
|
|
43
55
|
useCase: options.use_case,
|
|
@@ -53,32 +65,39 @@ function usePhoneAuth(config = {}) {
|
|
|
53
65
|
isLoading.value = false;
|
|
54
66
|
}
|
|
55
67
|
});
|
|
68
|
+
// Convenience methods
|
|
56
69
|
const getPhoneNumber = (options) => verify(Object.assign({ use_case: 'GetPhoneNumber' }, options));
|
|
57
70
|
const verifyPhoneNumber = (phoneNumber, options) => verify(Object.assign({ use_case: 'VerifyPhoneNumber', phone_number: phoneNumber }, options));
|
|
71
|
+
// Reset state
|
|
58
72
|
const reset = () => {
|
|
59
73
|
isLoading.value = false;
|
|
60
74
|
error.value = null;
|
|
61
75
|
result.value = null;
|
|
62
76
|
currentStep.value = 'idle';
|
|
63
77
|
};
|
|
78
|
+
// Expose granular methods directly from client for better discoverability
|
|
64
79
|
const preparePhoneRequest = client.preparePhoneRequest.bind(client);
|
|
65
80
|
const invokeSecurePrompt = client.invokeSecurePrompt.bind(client);
|
|
66
81
|
const getPhoneNumberCredential = client.getPhoneNumber.bind(client);
|
|
67
82
|
const verifyPhoneNumberCredential = client.verifyPhoneNumber.bind(client);
|
|
68
83
|
return {
|
|
84
|
+
// State (readonly)
|
|
69
85
|
isLoading: (0, vue_1.readonly)(isLoading),
|
|
70
86
|
error: (0, vue_1.readonly)(error),
|
|
71
87
|
result: (0, vue_1.readonly)(result),
|
|
72
88
|
currentStep: (0, vue_1.readonly)(currentStep),
|
|
73
89
|
isSupported: (0, vue_1.readonly)(isSupported),
|
|
90
|
+
// High-level methods
|
|
74
91
|
verify,
|
|
75
92
|
getPhoneNumber,
|
|
76
93
|
verifyPhoneNumber,
|
|
77
94
|
reset,
|
|
95
|
+
// Granular methods (directly exposed for better discoverability)
|
|
78
96
|
preparePhoneRequest,
|
|
79
97
|
invokeSecurePrompt,
|
|
80
98
|
getPhoneNumberCredential,
|
|
81
99
|
verifyPhoneNumberCredential,
|
|
100
|
+
// Client instance (still available for advanced usage)
|
|
82
101
|
client
|
|
83
102
|
};
|
|
84
103
|
}
|