@glideidentity/web-client-sdk 5.1.3 → 6.0.0-beta.2
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 +337 -526
- package/dist/browser/web-client-sdk.min.js +1 -1
- package/dist/cjs/adapters/index.js +15 -0
- package/dist/cjs/adapters/react.js +192 -0
- package/dist/cjs/adapters/vanilla.js +38 -0
- package/dist/cjs/adapters/vue.js +187 -0
- package/dist/cjs/browser.js +58 -0
- package/dist/cjs/client/http.js +159 -0
- package/dist/cjs/client/index.js +19 -0
- package/dist/cjs/client/logger.js +135 -0
- package/dist/cjs/client/phone-auth-client.js +428 -0
- package/dist/cjs/client/strategies/polling.js +177 -0
- package/dist/cjs/core/errors.js +204 -0
- package/dist/cjs/core/index.js +83 -0
- package/dist/cjs/core/type-guards.js +196 -0
- package/dist/cjs/core/types.js +25 -0
- package/dist/{core/phone-auth/validation-utils.js → cjs/core/validators.js} +70 -23
- package/dist/cjs/index.js +81 -0
- package/dist/cjs/ui/index.js +11 -0
- package/dist/{core/phone-auth → cjs}/ui/mobile-debug-console.js +149 -78
- package/dist/cjs/ui/modal.js +1122 -0
- package/dist/esm/adapters/index.js +11 -0
- package/dist/esm/adapters/react.js +182 -0
- package/dist/esm/adapters/vanilla.js +29 -0
- package/dist/esm/adapters/vue.js +177 -0
- package/dist/esm/browser.js +30 -11
- package/dist/esm/client/http.js +156 -0
- package/dist/esm/client/index.js +11 -0
- package/dist/esm/client/logger.js +131 -0
- package/dist/esm/client/phone-auth-client.js +424 -0
- package/dist/esm/client/strategies/polling.js +174 -0
- package/dist/esm/core/errors.js +193 -0
- package/dist/esm/core/index.js +60 -0
- package/dist/esm/core/type-guards.js +181 -0
- package/dist/esm/core/types.js +22 -1
- package/dist/esm/core/{phone-auth/validation-utils.js → validators.js} +66 -21
- package/dist/esm/index.js +45 -17
- package/dist/esm/ui/index.js +5 -0
- package/dist/esm/{core/phone-auth/ui → ui}/mobile-debug-console.js +149 -78
- package/dist/esm/ui/modal.js +1117 -0
- package/dist/types/adapters/index.d.ts +10 -0
- package/dist/types/adapters/index.d.ts.map +1 -0
- package/dist/types/adapters/react.d.ts +70 -0
- package/dist/types/adapters/react.d.ts.map +1 -0
- package/dist/types/adapters/vanilla.d.ts +29 -0
- package/dist/types/adapters/vanilla.d.ts.map +1 -0
- package/dist/types/adapters/vue.d.ts +71 -0
- package/dist/types/adapters/vue.d.ts.map +1 -0
- package/dist/types/browser.d.ts +27 -0
- package/dist/types/browser.d.ts.map +1 -0
- package/dist/types/client/http.d.ts +41 -0
- package/dist/types/client/http.d.ts.map +1 -0
- package/dist/types/client/index.d.ts +10 -0
- package/dist/types/client/index.d.ts.map +1 -0
- package/dist/types/client/logger.d.ts +36 -0
- package/dist/types/client/logger.d.ts.map +1 -0
- package/dist/types/client/phone-auth-client.d.ts +91 -0
- package/dist/types/client/phone-auth-client.d.ts.map +1 -0
- package/dist/types/client/strategies/polling.d.ts +36 -0
- package/dist/types/client/strategies/polling.d.ts.map +1 -0
- package/dist/types/core/errors.d.ts +71 -0
- package/dist/types/core/errors.d.ts.map +1 -0
- package/dist/types/core/index.d.ts +38 -0
- package/dist/types/core/index.d.ts.map +1 -0
- package/dist/types/core/type-guards.d.ts +118 -0
- package/dist/types/core/type-guards.d.ts.map +1 -0
- package/dist/types/core/types.d.ts +535 -0
- package/dist/types/core/types.d.ts.map +1 -0
- package/dist/types/core/validators.d.ts +63 -0
- package/dist/types/core/validators.d.ts.map +1 -0
- package/dist/types/index.d.ts +40 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/ui/index.d.ts +6 -0
- package/dist/types/ui/index.d.ts.map +1 -0
- package/dist/{esm/core/phone-auth → types}/ui/mobile-debug-console.d.ts +1 -0
- package/dist/types/ui/mobile-debug-console.d.ts.map +1 -0
- package/dist/types/ui/modal.d.ts +87 -0
- package/dist/types/ui/modal.d.ts.map +1 -0
- package/package.json +48 -34
- package/dist/adapters/angular/client.service.d.ts +0 -7
- package/dist/adapters/angular/client.service.js +0 -30
- package/dist/adapters/angular/index.d.ts +0 -3
- package/dist/adapters/angular/index.js +0 -18
- package/dist/adapters/angular/phone-auth.service.d.ts +0 -38
- package/dist/adapters/angular/phone-auth.service.js +0 -130
- package/dist/adapters/react/index.d.ts +0 -9
- package/dist/adapters/react/index.js +0 -28
- package/dist/adapters/react/useClient.d.ts +0 -26
- package/dist/adapters/react/useClient.js +0 -121
- package/dist/adapters/react/usePhoneAuth.d.ts +0 -23
- package/dist/adapters/react/usePhoneAuth.js +0 -95
- package/dist/adapters/vanilla/client.d.ts +0 -8
- package/dist/adapters/vanilla/client.js +0 -33
- package/dist/adapters/vanilla/index.d.ts +0 -3
- package/dist/adapters/vanilla/index.js +0 -18
- package/dist/adapters/vanilla/phone-auth.d.ts +0 -46
- package/dist/adapters/vanilla/phone-auth.js +0 -138
- package/dist/adapters/vue/index.d.ts +0 -10
- package/dist/adapters/vue/index.js +0 -36
- package/dist/adapters/vue/useClient.d.ts +0 -115
- package/dist/adapters/vue/useClient.js +0 -131
- package/dist/adapters/vue/usePhoneAuth.d.ts +0 -94
- package/dist/adapters/vue/usePhoneAuth.js +0 -103
- package/dist/browser.d.ts +0 -7
- package/dist/browser.js +0 -31
- package/dist/core/client.d.ts +0 -22
- package/dist/core/client.js +0 -77
- package/dist/core/logger.d.ts +0 -130
- package/dist/core/logger.js +0 -370
- package/dist/core/phone-auth/api-types.d.ts +0 -593
- package/dist/core/phone-auth/api-types.js +0 -215
- package/dist/core/phone-auth/client.d.ts +0 -189
- package/dist/core/phone-auth/client.js +0 -1441
- package/dist/core/phone-auth/error-utils.d.ts +0 -110
- package/dist/core/phone-auth/error-utils.js +0 -350
- package/dist/core/phone-auth/index.d.ts +0 -7
- package/dist/core/phone-auth/index.js +0 -50
- package/dist/core/phone-auth/status-types.d.ts +0 -107
- package/dist/core/phone-auth/status-types.js +0 -31
- package/dist/core/phone-auth/strategies/desktop.d.ts +0 -122
- package/dist/core/phone-auth/strategies/desktop.js +0 -596
- package/dist/core/phone-auth/strategies/index.d.ts +0 -11
- package/dist/core/phone-auth/strategies/index.js +0 -15
- package/dist/core/phone-auth/strategies/link.d.ts +0 -89
- package/dist/core/phone-auth/strategies/link.js +0 -384
- package/dist/core/phone-auth/strategies/ts43.d.ts +0 -32
- package/dist/core/phone-auth/strategies/ts43.js +0 -161
- package/dist/core/phone-auth/strategies/types.d.ts +0 -18
- package/dist/core/phone-auth/strategies/types.js +0 -6
- package/dist/core/phone-auth/type-guards.d.ts +0 -143
- package/dist/core/phone-auth/type-guards.js +0 -198
- package/dist/core/phone-auth/types.d.ts +0 -237
- package/dist/core/phone-auth/types.js +0 -93
- package/dist/core/phone-auth/ui/mobile-debug-console.d.ts +0 -25
- package/dist/core/phone-auth/ui/modal.d.ts +0 -88
- package/dist/core/phone-auth/ui/modal.js +0 -598
- package/dist/core/phone-auth/validation-utils.d.ts +0 -44
- package/dist/core/types.d.ts +0 -62
- package/dist/core/types.js +0 -2
- package/dist/core/version.d.ts +0 -1
- package/dist/core/version.js +0 -5
- package/dist/esm/adapters/angular/client.service.d.ts +0 -7
- package/dist/esm/adapters/angular/client.service.js +0 -27
- package/dist/esm/adapters/angular/index.d.ts +0 -3
- package/dist/esm/adapters/angular/index.js +0 -4
- package/dist/esm/adapters/angular/phone-auth.service.d.ts +0 -38
- package/dist/esm/adapters/angular/phone-auth.service.js +0 -127
- package/dist/esm/adapters/react/index.d.ts +0 -9
- package/dist/esm/adapters/react/index.js +0 -8
- package/dist/esm/adapters/react/useClient.d.ts +0 -26
- package/dist/esm/adapters/react/useClient.js +0 -116
- package/dist/esm/adapters/react/usePhoneAuth.d.ts +0 -23
- package/dist/esm/adapters/react/usePhoneAuth.js +0 -92
- package/dist/esm/adapters/vanilla/client.d.ts +0 -8
- package/dist/esm/adapters/vanilla/client.js +0 -29
- package/dist/esm/adapters/vanilla/index.d.ts +0 -3
- package/dist/esm/adapters/vanilla/index.js +0 -4
- package/dist/esm/adapters/vanilla/phone-auth.d.ts +0 -46
- package/dist/esm/adapters/vanilla/phone-auth.js +0 -134
- package/dist/esm/adapters/vue/index.d.ts +0 -10
- package/dist/esm/adapters/vue/index.js +0 -11
- package/dist/esm/adapters/vue/useClient.d.ts +0 -115
- package/dist/esm/adapters/vue/useClient.js +0 -127
- package/dist/esm/adapters/vue/usePhoneAuth.d.ts +0 -94
- package/dist/esm/adapters/vue/usePhoneAuth.js +0 -100
- package/dist/esm/browser.d.ts +0 -7
- package/dist/esm/core/client.d.ts +0 -22
- package/dist/esm/core/client.js +0 -70
- package/dist/esm/core/logger.d.ts +0 -130
- package/dist/esm/core/logger.js +0 -359
- package/dist/esm/core/phone-auth/api-types.d.ts +0 -593
- package/dist/esm/core/phone-auth/api-types.js +0 -203
- package/dist/esm/core/phone-auth/client.d.ts +0 -189
- package/dist/esm/core/phone-auth/client.js +0 -1404
- package/dist/esm/core/phone-auth/error-utils.d.ts +0 -110
- package/dist/esm/core/phone-auth/error-utils.js +0 -338
- package/dist/esm/core/phone-auth/index.d.ts +0 -7
- package/dist/esm/core/phone-auth/index.js +0 -8
- package/dist/esm/core/phone-auth/status-types.d.ts +0 -107
- package/dist/esm/core/phone-auth/status-types.js +0 -26
- package/dist/esm/core/phone-auth/strategies/desktop.d.ts +0 -122
- package/dist/esm/core/phone-auth/strategies/desktop.js +0 -590
- package/dist/esm/core/phone-auth/strategies/index.d.ts +0 -11
- package/dist/esm/core/phone-auth/strategies/index.js +0 -7
- package/dist/esm/core/phone-auth/strategies/link.d.ts +0 -89
- package/dist/esm/core/phone-auth/strategies/link.js +0 -380
- package/dist/esm/core/phone-auth/strategies/ts43.d.ts +0 -32
- package/dist/esm/core/phone-auth/strategies/ts43.js +0 -157
- package/dist/esm/core/phone-auth/strategies/types.d.ts +0 -18
- package/dist/esm/core/phone-auth/strategies/types.js +0 -5
- package/dist/esm/core/phone-auth/type-guards.d.ts +0 -143
- package/dist/esm/core/phone-auth/type-guards.js +0 -185
- package/dist/esm/core/phone-auth/types.d.ts +0 -237
- package/dist/esm/core/phone-auth/types.js +0 -76
- package/dist/esm/core/phone-auth/ui/modal.d.ts +0 -88
- package/dist/esm/core/phone-auth/ui/modal.js +0 -594
- package/dist/esm/core/phone-auth/validation-utils.d.ts +0 -44
- package/dist/esm/core/types.d.ts +0 -62
- package/dist/esm/core/version.d.ts +0 -1
- package/dist/esm/core/version.js +0 -2
- package/dist/esm/index.d.ts +0 -12
- package/dist/index.d.ts +0 -12
- package/dist/index.js +0 -55
package/README.md
CHANGED
|
@@ -1,43 +1,16 @@
|
|
|
1
1
|
# Glide Web Client SDK
|
|
2
2
|
|
|
3
|
-
The official web SDK for integrating Glide's carrier-grade phone verification into your web applications.
|
|
3
|
+
The official web SDK for integrating Glide's carrier-grade phone verification into your web applications.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- 🚀 **Instant Verification
|
|
8
|
-
- 🔐 **Fraud Resistant
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
- 🛡️ **Type Safe**: Full TypeScript support with type guards and IntelliSense
|
|
15
|
-
- 🎯 **Developer Friendly**: Clear error messages and browser compatibility checks
|
|
16
|
-
|
|
17
|
-
## What's New in v4.4
|
|
18
|
-
|
|
19
|
-
### 🎉 Enhanced Control & Better DX
|
|
20
|
-
- **Extended Mode**: More control with `executionMode: 'extended'` for granular authentication flow
|
|
21
|
-
- **Prevent Default UI**: Use `preventDefaultUI: true` to disable all SDK modals
|
|
22
|
-
- **Type Guards**: Helper functions for type-safe result handling
|
|
23
|
-
- **Unified Trigger Pattern**: Consistent `trigger()` function for all strategies
|
|
24
|
-
- **Auto-Trigger Support**: Automatic App Clip opening with retry capability
|
|
25
|
-
- **TypeScript Enhancements**: Full IntelliSense and type safety
|
|
26
|
-
- **Faster Timeout**: Polling timeout reduced to 1 minute for better UX
|
|
27
|
-
- **Dual-Platform QR**: Support for iOS and Android specific QR codes
|
|
28
|
-
|
|
29
|
-
## Table of Contents
|
|
30
|
-
|
|
31
|
-
- [Installation](#installation)
|
|
32
|
-
- [Development](#development)
|
|
33
|
-
- [Quick Start](#quick-start)
|
|
34
|
-
- [Extended Mode - Advanced Control](#extended-mode---advanced-control)
|
|
35
|
-
- [Authentication Strategies](#authentication-strategies)
|
|
36
|
-
- [Framework Examples](#framework-examples)
|
|
37
|
-
- [Error Handling](#error-handling)
|
|
38
|
-
- [Browser Support](#browser-support)
|
|
39
|
-
- [API Reference](#api-reference)
|
|
40
|
-
- [Documentation](#documentation)
|
|
7
|
+
- 🚀 **Instant Verification** - Direct carrier verification without SMS delays
|
|
8
|
+
- 🔐 **Fraud Resistant** - Can't be intercepted or spoofed like SMS codes
|
|
9
|
+
- 📱 **Multi-Platform** - Desktop QR codes, iOS App Clips, Android deep links
|
|
10
|
+
- 🎨 **Customizable UI** - Built-in modal with themes and view modes
|
|
11
|
+
- 🔧 **Flexible Architecture** - Use the full SDK or just the core types
|
|
12
|
+
- 🌐 **Framework Support** - React, Vue, Angular, and vanilla JavaScript
|
|
13
|
+
- 📦 **Tree-Shakeable** - Import only what you need
|
|
41
14
|
|
|
42
15
|
## Installation
|
|
43
16
|
|
|
@@ -45,617 +18,455 @@ The official web SDK for integrating Glide's carrier-grade phone verification in
|
|
|
45
18
|
npm install @glideidentity/web-client-sdk
|
|
46
19
|
```
|
|
47
20
|
|
|
48
|
-
##
|
|
49
|
-
|
|
50
|
-
### Using Docker (Recommended)
|
|
21
|
+
## Quick Start
|
|
51
22
|
|
|
52
|
-
|
|
53
|
-
# Build the SDK
|
|
54
|
-
docker compose run --rm build
|
|
23
|
+
### High-Level API (Recommended)
|
|
55
24
|
|
|
56
|
-
|
|
57
|
-
docker compose run --rm test
|
|
25
|
+
The simplest way to integrate phone verification:
|
|
58
26
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
### Without Docker
|
|
27
|
+
```javascript
|
|
28
|
+
import { PhoneAuthClient, USE_CASE } from '@glideidentity/web-client-sdk';
|
|
64
29
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
30
|
+
const client = new PhoneAuthClient({
|
|
31
|
+
endpoints: {
|
|
32
|
+
prepare: '/api/phone-auth/prepare',
|
|
33
|
+
process: '/api/phone-auth/process',
|
|
34
|
+
}
|
|
35
|
+
});
|
|
68
36
|
|
|
69
|
-
|
|
70
|
-
|
|
37
|
+
// Get a phone number
|
|
38
|
+
const result = await client.authenticate({
|
|
39
|
+
use_case: USE_CASE.GET_PHONE_NUMBER
|
|
40
|
+
});
|
|
41
|
+
console.log('Phone:', result.phone_number);
|
|
71
42
|
|
|
72
|
-
|
|
73
|
-
|
|
43
|
+
// Or verify a specific number
|
|
44
|
+
const verified = await client.authenticate({
|
|
45
|
+
use_case: USE_CASE.VERIFY_PHONE_NUMBER,
|
|
46
|
+
phone_number: '+14155551234'
|
|
47
|
+
});
|
|
48
|
+
console.log('Verified:', verified.verified);
|
|
74
49
|
```
|
|
75
50
|
|
|
76
|
-
|
|
51
|
+
### Granular API
|
|
77
52
|
|
|
78
|
-
|
|
53
|
+
For more control over the authentication flow:
|
|
79
54
|
|
|
80
|
-
```
|
|
81
|
-
import
|
|
82
|
-
import { PhoneAuthClient } from '@glideidentity/web-client-sdk';
|
|
55
|
+
```javascript
|
|
56
|
+
import { PhoneAuthClient, USE_CASE } from '@glideidentity/web-client-sdk';
|
|
83
57
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
58
|
+
const client = new PhoneAuthClient({
|
|
59
|
+
endpoints: {
|
|
60
|
+
prepare: '/api/phone-auth/prepare',
|
|
61
|
+
process: '/api/phone-auth/process',
|
|
62
|
+
}
|
|
63
|
+
});
|
|
90
64
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
// Invoke authentication (SDK handles UI by default)
|
|
99
|
-
const credential = await phoneAuth.invokeSecurePrompt(prepareResult);
|
|
100
|
-
|
|
101
|
-
// Process the credential
|
|
102
|
-
const result = await phoneAuth.getPhoneNumber(
|
|
103
|
-
credential,
|
|
104
|
-
prepareResult.session
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
console.log('Phone number:', result.phone_number);
|
|
108
|
-
} catch (error) {
|
|
109
|
-
console.error('Verification failed:', error);
|
|
110
|
-
}
|
|
111
|
-
};
|
|
65
|
+
// Step 1: Prepare the request
|
|
66
|
+
const prepared = await client.prepare({
|
|
67
|
+
use_case: USE_CASE.VERIFY_PHONE_NUMBER,
|
|
68
|
+
phone_number: '+14155551234'
|
|
69
|
+
});
|
|
112
70
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const prepareResult = await phoneAuth.preparePhoneRequest({
|
|
117
|
-
use_case: 'VerifyPhoneNumber',
|
|
118
|
-
phone_number: '+14155551234'
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
// Invoke authentication
|
|
122
|
-
const credential = await phoneAuth.invokeSecurePrompt(prepareResult);
|
|
123
|
-
|
|
124
|
-
// Verify the number
|
|
125
|
-
const result = await phoneAuth.verifyPhoneNumber(
|
|
126
|
-
credential,
|
|
127
|
-
prepareResult.session
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
console.log('Verified:', result.verified);
|
|
131
|
-
} catch (error) {
|
|
132
|
-
console.error('Verification failed:', error);
|
|
133
|
-
}
|
|
134
|
-
};
|
|
71
|
+
// Step 2: Invoke authentication (shows UI based on strategy)
|
|
72
|
+
const invokeResult = await client.invokeSecurePrompt(prepared);
|
|
73
|
+
const credential = await invokeResult.credential;
|
|
135
74
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
<button onClick={handleGetPhoneNumber}>
|
|
139
|
-
Get Phone Number
|
|
140
|
-
</button>
|
|
141
|
-
<button onClick={handleVerifyPhoneNumber}>
|
|
142
|
-
Verify Phone Number
|
|
143
|
-
</button>
|
|
144
|
-
</div>
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
```
|
|
75
|
+
// Step 3: Process the credential
|
|
76
|
+
const result = await client.verifyPhoneNumber(credential, invokeResult.session);
|
|
148
77
|
|
|
149
|
-
|
|
78
|
+
console.log('Verified:', result.verified);
|
|
79
|
+
```
|
|
150
80
|
|
|
151
|
-
|
|
81
|
+
## Configuration
|
|
152
82
|
|
|
153
|
-
###
|
|
83
|
+
### Client Options
|
|
154
84
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
85
|
+
```typescript
|
|
86
|
+
const client = new PhoneAuthClient({
|
|
87
|
+
// Required: Your backend endpoints
|
|
88
|
+
endpoints: {
|
|
89
|
+
prepare: '/api/phone-auth/prepare', // Prepare request endpoint
|
|
90
|
+
process: '/api/phone-auth/process', // Process credential endpoint
|
|
91
|
+
polling: '/api/phone-auth/status', // Optional: Status polling endpoint
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
// Polling configuration
|
|
95
|
+
pollingInterval: 2000, // Polling interval in ms (default: 2000)
|
|
96
|
+
maxPollingAttempts: 30, // Max attempts before timeout (default: 30)
|
|
97
|
+
timeout: 30000, // API request timeout in ms (default: 30000)
|
|
98
|
+
|
|
99
|
+
// Debug options
|
|
100
|
+
debug: false, // Enable console logging (default: false)
|
|
101
|
+
devtools: {
|
|
102
|
+
showMobileConsole: false // Show on-screen console on mobile (default: false)
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
```
|
|
162
106
|
|
|
163
|
-
###
|
|
107
|
+
### Invoke Options
|
|
164
108
|
|
|
165
|
-
|
|
166
|
-
// Enable extended mode for granular control
|
|
167
|
-
const result = await phoneAuth.invokeSecurePrompt(prepareResult, {
|
|
168
|
-
executionMode: 'extended',
|
|
169
|
-
preventDefaultUI: true // Optional: disable all SDK UI
|
|
170
|
-
});
|
|
109
|
+
Customize the authentication UI and behavior:
|
|
171
110
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
//
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
// Start polling when ready (only if preventDefaultUI was true)
|
|
178
|
-
if (result.start_polling) {
|
|
179
|
-
const credential = await result.start_polling();
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Or wait for credential
|
|
183
|
-
const credential = await result.credential;
|
|
111
|
+
```typescript
|
|
112
|
+
const result = await client.invokeSecurePrompt(prepared, {
|
|
113
|
+
// Prevent SDK from showing any UI (use your own)
|
|
114
|
+
preventDefaultUI: false,
|
|
184
115
|
|
|
185
|
-
//
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (result.strategy === 'link') {
|
|
190
|
-
// Re-trigger app opening
|
|
191
|
-
result.trigger();
|
|
116
|
+
// Polling configuration (overrides client config)
|
|
117
|
+
pollingInterval: 2000,
|
|
118
|
+
maxPollingAttempts: 30,
|
|
192
119
|
|
|
193
|
-
//
|
|
194
|
-
|
|
195
|
-
|
|
120
|
+
// Modal customization (for desktop QR strategy)
|
|
121
|
+
modalOptions: {
|
|
122
|
+
theme: 'auto', // 'dark' | 'light' | 'auto'
|
|
123
|
+
viewMode: 'toggle', // 'toggle' | 'dual' | 'pre-step'
|
|
124
|
+
title: 'Scan to Verify', // Custom title text
|
|
125
|
+
description: '', // Optional subtitle
|
|
126
|
+
showCloseButton: true, // Show X button
|
|
127
|
+
closeOnBackdropClick: true, // Close on outside click
|
|
128
|
+
closeOnEscape: true, // Close on Escape key
|
|
196
129
|
}
|
|
197
|
-
|
|
198
|
-
// Wait for completion
|
|
199
|
-
const credential = await result.credential;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
if (result.strategy === 'ts43') {
|
|
203
|
-
// Trigger when user is ready
|
|
204
|
-
await result.trigger();
|
|
205
|
-
|
|
206
|
-
// Get credential
|
|
207
|
-
const credential = await result.credential;
|
|
208
|
-
}
|
|
130
|
+
});
|
|
209
131
|
```
|
|
210
132
|
|
|
211
|
-
|
|
133
|
+
## Modal Customization
|
|
212
134
|
|
|
213
|
-
|
|
214
|
-
interface ExtendedResponse {
|
|
215
|
-
strategy: 'desktop' | 'link' | 'ts43';
|
|
216
|
-
session: SessionInfo;
|
|
217
|
-
credential: Promise<AuthCredential>;
|
|
218
|
-
cancel: () => void;
|
|
219
|
-
}
|
|
135
|
+
The SDK provides a built-in modal for desktop QR code display.
|
|
220
136
|
|
|
221
|
-
|
|
222
|
-
qr_code_data: {
|
|
223
|
-
ios_qr_image?: string;
|
|
224
|
-
android_qr_image?: string;
|
|
225
|
-
qr_code?: string;
|
|
226
|
-
};
|
|
227
|
-
start_polling?: () => Promise<AuthCredential>;
|
|
228
|
-
is_polling?: boolean;
|
|
229
|
-
}
|
|
137
|
+
### View Modes
|
|
230
138
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
start_polling?: () => Promise<AuthCredential>;
|
|
237
|
-
is_polling?: boolean;
|
|
238
|
-
}
|
|
139
|
+
| Mode | Description | Best For |
|
|
140
|
+
|------|-------------|----------|
|
|
141
|
+
| `toggle` | Single QR with iOS/Android switch | Clean, minimal UI (default) |
|
|
142
|
+
| `dual` | Side-by-side QR codes | Users who may not know their OS |
|
|
143
|
+
| `pre-step` | OS selection screen first | Guided experience |
|
|
239
144
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
145
|
+
### Themes
|
|
146
|
+
|
|
147
|
+
| Theme | Description |
|
|
148
|
+
|-------|-------------|
|
|
149
|
+
| `auto` | Follows system preference (default) |
|
|
150
|
+
| `dark` | Dark background with light text |
|
|
151
|
+
| `light` | Light background with dark text |
|
|
244
152
|
|
|
245
|
-
###
|
|
153
|
+
### Custom UI
|
|
246
154
|
|
|
247
|
-
|
|
155
|
+
To use your own UI instead of the built-in modal:
|
|
248
156
|
|
|
249
157
|
```javascript
|
|
250
|
-
|
|
251
|
-
const result = await phoneAuth.invokeSecurePrompt(prepareResult, {
|
|
252
|
-
executionMode: 'extended',
|
|
158
|
+
const result = await client.invokeSecurePrompt(prepared, {
|
|
253
159
|
preventDefaultUI: true
|
|
254
160
|
});
|
|
255
161
|
|
|
256
|
-
//
|
|
162
|
+
// For desktop strategy, display your own QR code
|
|
257
163
|
if (result.strategy === 'desktop') {
|
|
258
|
-
|
|
164
|
+
// Access QR data from the prepare response
|
|
165
|
+
const qrData = prepared.data;
|
|
166
|
+
displayYourQRCode(qrData.ios_qr_image, qrData.android_qr_image);
|
|
259
167
|
|
|
260
|
-
//
|
|
261
|
-
const credential = await result.
|
|
168
|
+
// Wait for credential
|
|
169
|
+
const credential = await result.credential;
|
|
170
|
+
|
|
171
|
+
// Or cancel if needed
|
|
172
|
+
result.cancel?.();
|
|
262
173
|
}
|
|
263
174
|
```
|
|
264
175
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
For continuing authentication from another device:
|
|
268
|
-
|
|
269
|
-
```javascript
|
|
270
|
-
// Desktop starts authentication
|
|
271
|
-
const desktopResult = await phoneAuth.preparePhoneRequest({
|
|
272
|
-
use_case: 'GetPhoneNumber'
|
|
273
|
-
});
|
|
176
|
+
## Authentication Strategies
|
|
274
177
|
|
|
275
|
-
|
|
276
|
-
const mobileResult = await phoneAuth.preparePhoneRequest({
|
|
277
|
-
parent_session_id: desktopResult.session.session_id
|
|
278
|
-
// use_case inherited from parent
|
|
279
|
-
});
|
|
178
|
+
The SDK automatically selects the best strategy based on the device:
|
|
280
179
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
180
|
+
| Strategy | Platform | Description |
|
|
181
|
+
|----------|----------|-------------|
|
|
182
|
+
| `ts43` | Android Chrome 128+ | Native Digital Credentials API |
|
|
183
|
+
| `link` | iOS / Android | App Clip (iOS) or carrier app (Android) |
|
|
184
|
+
| `desktop` | Desktop browsers | QR code scanned by mobile |
|
|
284
185
|
|
|
285
|
-
|
|
186
|
+
### Strategy-Specific Handling
|
|
286
187
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
### Desktop Strategy (QR Code)
|
|
290
|
-
- **When**: Desktop browsers
|
|
291
|
-
- **How**: Displays QR code for mobile scanning
|
|
292
|
-
- **Default**: Shows built-in QR modal
|
|
293
|
-
- **Custom**: Use `preventDefaultUI: true` to handle QR display yourself
|
|
188
|
+
```javascript
|
|
189
|
+
const result = await client.invokeSecurePrompt(prepared);
|
|
294
190
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
191
|
+
switch (result.strategy) {
|
|
192
|
+
case 'ts43':
|
|
193
|
+
// Android: Credential returned directly
|
|
194
|
+
const credential = await result.credential;
|
|
195
|
+
break;
|
|
196
|
+
|
|
197
|
+
case 'link':
|
|
198
|
+
// iOS: Opens App Clip, polls for completion
|
|
199
|
+
// Android: Opens carrier's privileged app, polls for completion
|
|
200
|
+
const credential = await result.credential;
|
|
201
|
+
// Optionally cancel polling
|
|
202
|
+
result.cancel?.();
|
|
203
|
+
break;
|
|
204
|
+
|
|
205
|
+
case 'desktop':
|
|
206
|
+
// Desktop: Shows QR modal, polls for completion
|
|
207
|
+
const credential = await result.credential;
|
|
208
|
+
result.cancel?.();
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
```
|
|
300
212
|
|
|
301
|
-
|
|
302
|
-
- **When**: Chrome/Edge on Android with Digital Credentials API
|
|
303
|
-
- **How**: Uses browser's native credential prompt
|
|
304
|
-
- **Default**: Shows credential prompt immediately
|
|
305
|
-
- **Custom**: Control timing with `trigger()` in extended mode
|
|
213
|
+
## Framework Integration
|
|
306
214
|
|
|
307
|
-
|
|
215
|
+
### React
|
|
308
216
|
|
|
309
|
-
|
|
217
|
+
```jsx
|
|
218
|
+
import { usePhoneAuth, USE_CASE } from '@glideidentity/web-client-sdk/react';
|
|
310
219
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
}
|
|
220
|
+
function PhoneVerification() {
|
|
221
|
+
const { authenticate, isLoading, error, result } = usePhoneAuth({
|
|
222
|
+
endpoints: {
|
|
223
|
+
prepare: '/api/phone-auth/prepare',
|
|
224
|
+
process: '/api/phone-auth/process',
|
|
225
|
+
}
|
|
226
|
+
});
|
|
318
227
|
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
|
|
228
|
+
const handleVerify = async () => {
|
|
229
|
+
try {
|
|
230
|
+
const result = await authenticate({
|
|
231
|
+
use_case: USE_CASE.VERIFY_PHONE_NUMBER,
|
|
232
|
+
phone_number: '+14155551234'
|
|
233
|
+
});
|
|
234
|
+
console.log('Verified:', result.verified);
|
|
235
|
+
} catch (err) {
|
|
236
|
+
console.error('Failed:', err);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
322
239
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
if (isDesktopStrategy(result)) {
|
|
329
|
-
// TypeScript knows this is DesktopExtendedResponse
|
|
330
|
-
console.log('QR data:', result.qr_code_data);
|
|
331
|
-
} else if (isLinkStrategy(result)) {
|
|
332
|
-
// TypeScript knows this is LinkExtendedResponse
|
|
333
|
-
console.log('App URL:', result.data.app_url);
|
|
334
|
-
} else if (isTS43Strategy(result)) {
|
|
335
|
-
// TypeScript knows this is TS43ExtendedResponse
|
|
336
|
-
await result.trigger();
|
|
337
|
-
}
|
|
338
|
-
} else {
|
|
339
|
-
// Standard mode - got credential directly
|
|
340
|
-
const verified = await phoneAuth.verifyPhoneNumber(result, session);
|
|
240
|
+
return (
|
|
241
|
+
<button onClick={handleVerify} disabled={isLoading}>
|
|
242
|
+
{isLoading ? 'Verifying...' : 'Verify Phone'}
|
|
243
|
+
</button>
|
|
244
|
+
);
|
|
341
245
|
}
|
|
342
246
|
```
|
|
343
247
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
### Vue 3 Example
|
|
248
|
+
### Vue
|
|
347
249
|
|
|
348
250
|
```vue
|
|
349
|
-
<template>
|
|
350
|
-
<div>
|
|
351
|
-
<button @click="verifyPhone" :disabled="isLoading">
|
|
352
|
-
Verify Phone
|
|
353
|
-
</button>
|
|
354
|
-
|
|
355
|
-
<div v-if="result">
|
|
356
|
-
Phone: {{ result.phone_number }}
|
|
357
|
-
</div>
|
|
358
|
-
</div>
|
|
359
|
-
</template>
|
|
360
|
-
|
|
361
251
|
<script setup>
|
|
362
|
-
import {
|
|
363
|
-
import { PhoneAuthClient } from '@glideidentity/web-client-sdk';
|
|
252
|
+
import { usePhoneAuth, USE_CASE } from '@glideidentity/web-client-sdk/vue';
|
|
364
253
|
|
|
365
|
-
const
|
|
366
|
-
|
|
254
|
+
const { authenticate, isLoading, error, result } = usePhoneAuth({
|
|
255
|
+
endpoints: {
|
|
256
|
+
prepare: '/api/phone-auth/prepare',
|
|
257
|
+
process: '/api/phone-auth/process',
|
|
258
|
+
}
|
|
367
259
|
});
|
|
368
260
|
|
|
369
|
-
const
|
|
370
|
-
|
|
261
|
+
const handleVerify = async () => {
|
|
262
|
+
await authenticate({
|
|
263
|
+
use_case: USE_CASE.VERIFY_PHONE_NUMBER,
|
|
264
|
+
phone_number: '+14155551234'
|
|
265
|
+
});
|
|
266
|
+
};
|
|
267
|
+
</script>
|
|
371
268
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
269
|
+
<template>
|
|
270
|
+
<button @click="handleVerify" :disabled="isLoading">
|
|
271
|
+
{{ isLoading ? 'Verifying...' : 'Verify Phone' }}
|
|
272
|
+
</button>
|
|
273
|
+
</template>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Vanilla JavaScript (Browser)
|
|
277
|
+
|
|
278
|
+
```html
|
|
279
|
+
<script src="https://unpkg.com/@glideidentity/web-client-sdk/dist/browser/web-client-sdk.min.js"></script>
|
|
280
|
+
<script>
|
|
281
|
+
const { PhoneAuthClient, USE_CASE } = GlideWebClientSDK;
|
|
282
|
+
|
|
283
|
+
const client = new PhoneAuthClient({
|
|
284
|
+
endpoints: {
|
|
285
|
+
prepare: '/api/phone-auth/prepare',
|
|
286
|
+
process: '/api/phone-auth/process',
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
document.getElementById('verify-btn').onclick = async () => {
|
|
291
|
+
const result = await client.authenticate({
|
|
292
|
+
use_case: USE_CASE.VERIFY_PHONE_NUMBER,
|
|
377
293
|
phone_number: '+14155551234'
|
|
378
294
|
});
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
result.value = await phoneAuth.verifyPhoneNumber(
|
|
382
|
-
credential,
|
|
383
|
-
prepared.session
|
|
384
|
-
);
|
|
385
|
-
} catch (error) {
|
|
386
|
-
console.error('Failed:', error);
|
|
387
|
-
} finally {
|
|
388
|
-
isLoading.value = false;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
295
|
+
console.log('Verified:', result.verified);
|
|
296
|
+
};
|
|
391
297
|
</script>
|
|
392
298
|
```
|
|
393
299
|
|
|
394
|
-
|
|
300
|
+
## Advanced Features
|
|
395
301
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
<div *ngIf="result">
|
|
408
|
-
Phone: {{ result.phone_number }}
|
|
409
|
-
</div>
|
|
410
|
-
`
|
|
411
|
-
})
|
|
412
|
-
export class PhoneVerifyComponent {
|
|
413
|
-
phoneAuth = new PhoneAuthClient({
|
|
414
|
-
// Optional configuration
|
|
415
|
-
debug: false
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
isLoading = false;
|
|
419
|
-
result: any = null;
|
|
420
|
-
|
|
421
|
-
async verify() {
|
|
422
|
-
this.isLoading = true;
|
|
423
|
-
try {
|
|
424
|
-
const prepared = await this.phoneAuth.preparePhoneRequest({
|
|
425
|
-
use_case: 'VerifyPhoneNumber',
|
|
426
|
-
phone_number: '+14155551234'
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
const credential = await this.phoneAuth.invokeSecurePrompt(prepared);
|
|
430
|
-
this.result = await this.phoneAuth.verifyPhoneNumber(
|
|
431
|
-
credential,
|
|
432
|
-
prepared.session
|
|
433
|
-
);
|
|
434
|
-
} catch (error) {
|
|
435
|
-
console.error('Failed:', error);
|
|
436
|
-
} finally {
|
|
437
|
-
this.isLoading = false;
|
|
302
|
+
### Custom HTTP Headers
|
|
303
|
+
|
|
304
|
+
Add custom headers to all SDK requests:
|
|
305
|
+
|
|
306
|
+
```javascript
|
|
307
|
+
const client = new PhoneAuthClient({
|
|
308
|
+
endpoints: { ... },
|
|
309
|
+
headers: {
|
|
310
|
+
common: {
|
|
311
|
+
'X-Custom-Header': 'your-value'
|
|
438
312
|
}
|
|
439
313
|
}
|
|
440
|
-
}
|
|
314
|
+
});
|
|
441
315
|
```
|
|
442
316
|
|
|
443
|
-
###
|
|
317
|
+
### Custom Logger
|
|
444
318
|
|
|
445
|
-
|
|
446
|
-
import { PhoneAuthClient } from '@glideidentity/web-client-sdk';
|
|
319
|
+
Provide your own logger implementation:
|
|
447
320
|
|
|
321
|
+
```javascript
|
|
448
322
|
const client = new PhoneAuthClient({
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
323
|
+
endpoints: { ... },
|
|
324
|
+
logger: {
|
|
325
|
+
debug: (msg, data) => console.debug('[SDK]', msg, data),
|
|
326
|
+
info: (msg, data) => console.info('[SDK]', msg, data),
|
|
327
|
+
warn: (msg, data) => console.warn('[SDK]', msg, data),
|
|
328
|
+
error: (msg, data) => console.error('[SDK]', msg, data),
|
|
329
|
+
}
|
|
452
330
|
});
|
|
331
|
+
```
|
|
453
332
|
|
|
454
|
-
|
|
455
|
-
async function getPhoneNumber() {
|
|
456
|
-
try {
|
|
457
|
-
const prepareResult = await client.preparePhoneRequest({
|
|
458
|
-
use_case: 'GetPhoneNumber'
|
|
459
|
-
});
|
|
460
|
-
|
|
461
|
-
const credential = await client.invokeSecurePrompt(prepareResult);
|
|
462
|
-
|
|
463
|
-
const result = await client.getPhoneNumber(
|
|
464
|
-
credential,
|
|
465
|
-
prepareResult.session
|
|
466
|
-
);
|
|
467
|
-
|
|
468
|
-
console.log('Phone:', result.phone_number);
|
|
469
|
-
} catch (error) {
|
|
470
|
-
console.error('Failed:', error);
|
|
471
|
-
}
|
|
472
|
-
}
|
|
333
|
+
### Custom HTTP Client
|
|
473
334
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
// Handle based on strategy
|
|
488
|
-
if (extendedResult.strategy === 'desktop') {
|
|
489
|
-
// Show custom QR
|
|
490
|
-
document.getElementById('qr').src = extendedResult.qr_code_data.qr_code;
|
|
491
|
-
|
|
492
|
-
// Start polling
|
|
493
|
-
const credential = await extendedResult.start_polling();
|
|
494
|
-
console.log('Verified!');
|
|
335
|
+
Bring your own HTTP client for full control:
|
|
336
|
+
|
|
337
|
+
```javascript
|
|
338
|
+
const client = new PhoneAuthClient({
|
|
339
|
+
endpoints: { ... },
|
|
340
|
+
httpClient: {
|
|
341
|
+
post: async (url, body, options) => {
|
|
342
|
+
const response = await yourHttpLib.post(url, body, options);
|
|
343
|
+
return response.data;
|
|
344
|
+
},
|
|
345
|
+
get: async (url, options) => {
|
|
346
|
+
const response = await yourHttpLib.get(url, options);
|
|
347
|
+
return response.data;
|
|
495
348
|
}
|
|
496
|
-
} catch (error) {
|
|
497
|
-
console.error('Failed:', error);
|
|
498
349
|
}
|
|
499
|
-
}
|
|
350
|
+
});
|
|
500
351
|
```
|
|
501
352
|
|
|
502
|
-
##
|
|
353
|
+
## Core Package
|
|
503
354
|
|
|
504
|
-
|
|
355
|
+
For advanced use cases, you can import just the types and validators without the full client:
|
|
505
356
|
|
|
506
|
-
```
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
357
|
+
```typescript
|
|
358
|
+
import {
|
|
359
|
+
// Types
|
|
360
|
+
type PrepareRequest,
|
|
361
|
+
type PrepareResponse,
|
|
362
|
+
type InvokeResult,
|
|
363
|
+
type SessionInfo,
|
|
512
364
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
## Browser Support
|
|
365
|
+
// Constants
|
|
366
|
+
USE_CASE,
|
|
367
|
+
AUTHENTICATION_STRATEGY,
|
|
368
|
+
ERROR_CODES,
|
|
369
|
+
|
|
370
|
+
// Validators
|
|
371
|
+
validatePhoneNumber,
|
|
372
|
+
validatePlmn,
|
|
373
|
+
|
|
374
|
+
// Type Guards
|
|
375
|
+
isTS43Strategy,
|
|
376
|
+
isLinkStrategy,
|
|
377
|
+
isDesktopStrategy,
|
|
378
|
+
isAuthError,
|
|
379
|
+
} from '@glideidentity/web-client-sdk/core';
|
|
530
380
|
|
|
531
|
-
|
|
381
|
+
// Use validators
|
|
382
|
+
const { valid, error } = validatePhoneNumber('+14155551234');
|
|
532
383
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
384
|
+
// Use type guards
|
|
385
|
+
if (isDesktopStrategy(result)) {
|
|
386
|
+
// TypeScript knows result has desktop-specific properties
|
|
387
|
+
}
|
|
388
|
+
```
|
|
536
389
|
|
|
537
|
-
|
|
390
|
+
## Error Handling
|
|
538
391
|
|
|
539
392
|
```javascript
|
|
540
|
-
|
|
541
|
-
const isSupported = phoneAuth.isSupported();
|
|
393
|
+
import { ERROR_CODES, isAuthError } from '@glideidentity/web-client-sdk';
|
|
542
394
|
|
|
543
|
-
|
|
544
|
-
|
|
395
|
+
try {
|
|
396
|
+
await client.authenticate({ ... });
|
|
397
|
+
} catch (error) {
|
|
398
|
+
if (isAuthError(error)) {
|
|
399
|
+
switch (error.code) {
|
|
400
|
+
case ERROR_CODES.USER_CANCELLED:
|
|
401
|
+
// User closed the modal or cancelled
|
|
402
|
+
break;
|
|
403
|
+
case ERROR_CODES.TIMEOUT:
|
|
404
|
+
// Authentication timed out
|
|
405
|
+
break;
|
|
406
|
+
case ERROR_CODES.NETWORK_ERROR:
|
|
407
|
+
// Network request failed
|
|
408
|
+
break;
|
|
409
|
+
default:
|
|
410
|
+
// Handle other errors
|
|
411
|
+
console.error(error.message);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
545
414
|
}
|
|
546
415
|
```
|
|
547
416
|
|
|
548
|
-
##
|
|
417
|
+
## Type Reference
|
|
549
418
|
|
|
550
|
-
###
|
|
419
|
+
### Use Cases
|
|
551
420
|
|
|
552
421
|
```typescript
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
};
|
|
559
|
-
pollingInterval?: number; // Polling interval in ms (default: 2000)
|
|
560
|
-
maxPollingAttempts?: number; // Max polling attempts (default: 30 = 1 minute)
|
|
561
|
-
timeout?: number; // API timeout in ms (default: 30000)
|
|
562
|
-
debug?: boolean; // Enable debug logging (default: false)
|
|
563
|
-
devtools?: {
|
|
564
|
-
showMobileConsole?: boolean; // Show debug console on mobile (default: false)
|
|
565
|
-
};
|
|
566
|
-
}
|
|
422
|
+
type UseCase = 'GetPhoneNumber' | 'VerifyPhoneNumber';
|
|
423
|
+
|
|
424
|
+
// Or use the constant
|
|
425
|
+
USE_CASE.GET_PHONE_NUMBER // 'GetPhoneNumber'
|
|
426
|
+
USE_CASE.VERIFY_PHONE_NUMBER // 'VerifyPhoneNumber'
|
|
567
427
|
```
|
|
568
428
|
|
|
569
|
-
###
|
|
429
|
+
### Prepare Request
|
|
570
430
|
|
|
571
431
|
```typescript
|
|
572
|
-
interface
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
// UI customization (when preventDefaultUI is false)
|
|
578
|
-
modalOptions?: {
|
|
579
|
-
className?: string;
|
|
580
|
-
title?: string;
|
|
581
|
-
description?: string;
|
|
582
|
-
buttonText?: string;
|
|
583
|
-
showCloseButton?: boolean;
|
|
584
|
-
};
|
|
585
|
-
|
|
586
|
-
// Callbacks
|
|
587
|
-
callbacks?: {
|
|
588
|
-
onOpen?: () => void;
|
|
589
|
-
onClose?: () => void;
|
|
590
|
-
onAuthStart?: () => void;
|
|
591
|
-
onAuthComplete?: (result: any) => void;
|
|
592
|
-
onError?: (error: Error) => void;
|
|
593
|
-
};
|
|
432
|
+
interface PrepareRequest {
|
|
433
|
+
use_case: UseCase;
|
|
434
|
+
phone_number?: string; // Required for VerifyPhoneNumber
|
|
435
|
+
parent_session_id?: string; // For cross-device flows
|
|
594
436
|
}
|
|
595
437
|
```
|
|
596
438
|
|
|
597
|
-
###
|
|
439
|
+
### Invoke Result
|
|
598
440
|
|
|
599
441
|
```typescript
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
// High-level convenience methods (full flow)
|
|
607
|
-
getPhoneNumberComplete(): Promise<GetPhoneNumberResponse>
|
|
608
|
-
verifyPhoneNumberComplete(phoneNumber: string): Promise<VerifyPhoneNumberResponse>
|
|
609
|
-
|
|
610
|
-
// Utility methods
|
|
611
|
-
isSupported(): boolean
|
|
442
|
+
interface InvokeResult {
|
|
443
|
+
strategy: 'ts43' | 'link' | 'desktop';
|
|
444
|
+
session: SessionInfo;
|
|
445
|
+
credential: Promise<AuthCredential>;
|
|
446
|
+
cancel?: () => void; // Available for link and desktop
|
|
447
|
+
}
|
|
612
448
|
```
|
|
613
449
|
|
|
614
|
-
###
|
|
450
|
+
### Responses
|
|
615
451
|
|
|
616
452
|
```typescript
|
|
617
|
-
interface PrepareRequest {
|
|
618
|
-
use_case: 'GetPhoneNumber' | 'VerifyPhoneNumber';
|
|
619
|
-
phone_number?: string;
|
|
620
|
-
parent_session_id?: string;
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
interface PrepareResponse {
|
|
624
|
-
authentication_strategy: 'desktop' | 'link' | 'ts43';
|
|
625
|
-
session: SessionInfo;
|
|
626
|
-
data: any;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
453
|
interface GetPhoneNumberResponse {
|
|
630
454
|
phone_number: string;
|
|
631
|
-
aud?: string;
|
|
632
455
|
}
|
|
633
456
|
|
|
634
457
|
interface VerifyPhoneNumberResponse {
|
|
635
458
|
phone_number: string;
|
|
636
459
|
verified: boolean;
|
|
637
|
-
aud?: string;
|
|
638
460
|
}
|
|
639
461
|
```
|
|
640
462
|
|
|
641
|
-
##
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
|
646
|
-
|
|
647
|
-
|
|
|
648
|
-
| [Phone Authentication](./docs/phone-auth.md) | Complete phone auth usage guide |
|
|
649
|
-
| [Desktop Authentication](./docs/desktop-auth.md) | QR code authentication flow |
|
|
650
|
-
| [Dual Platform QR](./docs/dual-platform-qr.md) | iOS/Android specific QR codes |
|
|
651
|
-
| [Error Handling](./docs/error-handling.md) | Error codes and handling strategies |
|
|
652
|
-
| [Trigger Pattern](./docs/trigger-pattern.md) | Consistent trigger API across strategies |
|
|
653
|
-
| [Implementation Notes](./docs/implementation-notes.md) | Technical implementation details |
|
|
654
|
-
| [Local Development](./docs/local-development.md) | Testing the SDK locally |
|
|
655
|
-
| [TS43 Data Flow](./docs/TS43_DATA_FLOW.md) | Digital Credentials API details |
|
|
656
|
-
| [Type Hierarchy](./docs/TYPE_HIERARCHY.md) | TypeScript type system |
|
|
657
|
-
| [Naming Conventions](./docs/NAMING_CONVENTIONS.md) | API naming standards |
|
|
658
|
-
| [Security Checklist](./docs/security-checklist.md) | NPM publishing security |
|
|
463
|
+
## Browser Support
|
|
464
|
+
|
|
465
|
+
| Browser | Strategy | Requirements |
|
|
466
|
+
|---------|----------|--------------|
|
|
467
|
+
| Chrome Android 128+ | TS43 | Digital Credentials API |
|
|
468
|
+
| Safari iOS | Link | App Clips support |
|
|
469
|
+
| Chrome/Edge/Firefox Desktop | Desktop | Any modern version |
|
|
659
470
|
|
|
660
471
|
## Support
|
|
661
472
|
|
|
@@ -664,4 +475,4 @@ For detailed documentation, see the [docs](./docs) folder:
|
|
|
664
475
|
|
|
665
476
|
## License
|
|
666
477
|
|
|
667
|
-
MIT
|
|
478
|
+
MIT
|