@glideidentity/web-client-sdk 5.1.2 → 6.0.0-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 +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 +439 -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 +435 -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 +534 -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 -151
- 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 -147
- 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
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework adapters for Phone Authentication SDK.
|
|
3
|
+
*
|
|
4
|
+
* Import from specific adapter paths for proper tree-shaking:
|
|
5
|
+
* - @glideidentity/web-client-sdk/react
|
|
6
|
+
* - @glideidentity/web-client-sdk/vue
|
|
7
|
+
* - @glideidentity/web-client-sdk/vanilla
|
|
8
|
+
*/
|
|
9
|
+
// Note: Don't import React/Vue here to avoid bundling framework deps
|
|
10
|
+
// Each adapter should be imported directly from its path
|
|
11
|
+
export { PhoneAuthClient } from '../client/phone-auth-client';
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Adapter for Phone Authentication SDK.
|
|
3
|
+
*
|
|
4
|
+
* Provides a React hook that wraps PhoneAuthClient with React state management.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```tsx
|
|
8
|
+
* import { usePhoneAuth } from '@glideidentity/web-client-sdk/react';
|
|
9
|
+
*
|
|
10
|
+
* function AuthButton() {
|
|
11
|
+
* const { authenticate, isLoading, error, result } = usePhoneAuth({ debug: true });
|
|
12
|
+
*
|
|
13
|
+
* const handleClick = async () => {
|
|
14
|
+
* try {
|
|
15
|
+
* const result = await authenticate({
|
|
16
|
+
* use_case: 'VerifyPhoneNumber',
|
|
17
|
+
* phone_number: '+14155551234'
|
|
18
|
+
* });
|
|
19
|
+
* console.log('Verified:', result.verified);
|
|
20
|
+
* } catch (err) {
|
|
21
|
+
* // Error is also in `error` state
|
|
22
|
+
* }
|
|
23
|
+
* };
|
|
24
|
+
*
|
|
25
|
+
* return (
|
|
26
|
+
* <button onClick={handleClick} disabled={isLoading}>
|
|
27
|
+
* {isLoading ? 'Verifying...' : 'Verify Phone'}
|
|
28
|
+
* </button>
|
|
29
|
+
* );
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
34
|
+
import { PhoneAuthClient } from '../client/phone-auth-client';
|
|
35
|
+
// Re-export PhoneAuthClient and core types/constants for convenience
|
|
36
|
+
export { PhoneAuthClient } from '../client/phone-auth-client';
|
|
37
|
+
export { USE_CASE, AUTHENTICATION_STRATEGY } from '../core/types';
|
|
38
|
+
export { ERROR_CODES, isAuthError, createAuthError } from '../core/errors';
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// HOOK
|
|
41
|
+
// ============================================================================
|
|
42
|
+
/**
|
|
43
|
+
* React hook for phone authentication.
|
|
44
|
+
*/
|
|
45
|
+
export function usePhoneAuth(config) {
|
|
46
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
47
|
+
const [error, setError] = useState(null);
|
|
48
|
+
const [result, setResult] = useState(null);
|
|
49
|
+
const [step, setStep] = useState('idle');
|
|
50
|
+
// Memoize client - recreate if config changes
|
|
51
|
+
// Using JSON.stringify for stable comparison of config object
|
|
52
|
+
const configKey = JSON.stringify(config);
|
|
53
|
+
const client = useMemo(() => new PhoneAuthClient(config), [configKey]);
|
|
54
|
+
const isSupported = useMemo(() => client.isSupported(), [client]);
|
|
55
|
+
/**
|
|
56
|
+
* High-level authentication.
|
|
57
|
+
*/
|
|
58
|
+
const authenticate = useCallback(async (request, options) => {
|
|
59
|
+
setIsLoading(true);
|
|
60
|
+
setError(null);
|
|
61
|
+
setStep('preparing');
|
|
62
|
+
try {
|
|
63
|
+
const authResult = await client.authenticate(request, options);
|
|
64
|
+
setResult(authResult);
|
|
65
|
+
setStep('complete');
|
|
66
|
+
return authResult;
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
const authError = err;
|
|
70
|
+
setError(authError);
|
|
71
|
+
setStep('error');
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
setIsLoading(false);
|
|
76
|
+
}
|
|
77
|
+
}, [client]);
|
|
78
|
+
/**
|
|
79
|
+
* Granular: Prepare.
|
|
80
|
+
*/
|
|
81
|
+
const prepare = useCallback(async (request) => {
|
|
82
|
+
setIsLoading(true);
|
|
83
|
+
setError(null);
|
|
84
|
+
setStep('preparing');
|
|
85
|
+
try {
|
|
86
|
+
const result = await client.prepare(request);
|
|
87
|
+
setStep('idle'); // Reset step on success (prepare is just first step)
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
const authError = err;
|
|
92
|
+
setError(authError);
|
|
93
|
+
setStep('error');
|
|
94
|
+
throw err;
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
setIsLoading(false);
|
|
98
|
+
}
|
|
99
|
+
}, [client]);
|
|
100
|
+
/**
|
|
101
|
+
* Granular: Invoke.
|
|
102
|
+
*/
|
|
103
|
+
const invokeSecurePrompt = useCallback(async (prepared, options) => {
|
|
104
|
+
setStep('invoking');
|
|
105
|
+
try {
|
|
106
|
+
return await client.invokeSecurePrompt(prepared, options);
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
const authError = err;
|
|
110
|
+
setError(authError);
|
|
111
|
+
setStep('error');
|
|
112
|
+
throw err;
|
|
113
|
+
}
|
|
114
|
+
}, [client]);
|
|
115
|
+
/**
|
|
116
|
+
* Granular: Get phone number.
|
|
117
|
+
*/
|
|
118
|
+
const getPhoneNumber = useCallback(async (credential, session) => {
|
|
119
|
+
setIsLoading(true);
|
|
120
|
+
setStep('processing');
|
|
121
|
+
try {
|
|
122
|
+
const authResult = await client.getPhoneNumber(credential, session);
|
|
123
|
+
setResult(authResult);
|
|
124
|
+
setStep('complete');
|
|
125
|
+
return authResult;
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
const authError = err;
|
|
129
|
+
setError(authError);
|
|
130
|
+
setStep('error');
|
|
131
|
+
throw err;
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
setIsLoading(false);
|
|
135
|
+
}
|
|
136
|
+
}, [client]);
|
|
137
|
+
/**
|
|
138
|
+
* Granular: Verify phone number.
|
|
139
|
+
*/
|
|
140
|
+
const verifyPhoneNumber = useCallback(async (credential, session) => {
|
|
141
|
+
setIsLoading(true);
|
|
142
|
+
setStep('processing');
|
|
143
|
+
try {
|
|
144
|
+
const authResult = await client.verifyPhoneNumber(credential, session);
|
|
145
|
+
setResult(authResult);
|
|
146
|
+
setStep('complete');
|
|
147
|
+
return authResult;
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
const authError = err;
|
|
151
|
+
setError(authError);
|
|
152
|
+
setStep('error');
|
|
153
|
+
throw err;
|
|
154
|
+
}
|
|
155
|
+
finally {
|
|
156
|
+
setIsLoading(false);
|
|
157
|
+
}
|
|
158
|
+
}, [client]);
|
|
159
|
+
/**
|
|
160
|
+
* Reset state.
|
|
161
|
+
*/
|
|
162
|
+
const reset = useCallback(() => {
|
|
163
|
+
setIsLoading(false);
|
|
164
|
+
setError(null);
|
|
165
|
+
setResult(null);
|
|
166
|
+
setStep('idle');
|
|
167
|
+
}, []);
|
|
168
|
+
return {
|
|
169
|
+
isLoading,
|
|
170
|
+
error,
|
|
171
|
+
result,
|
|
172
|
+
step,
|
|
173
|
+
isSupported,
|
|
174
|
+
authenticate,
|
|
175
|
+
prepare,
|
|
176
|
+
invokeSecurePrompt,
|
|
177
|
+
getPhoneNumber,
|
|
178
|
+
verifyPhoneNumber,
|
|
179
|
+
reset,
|
|
180
|
+
client,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vanilla JavaScript Adapter for Phone Authentication SDK.
|
|
3
|
+
*
|
|
4
|
+
* Simply re-exports the PhoneAuthClient for use without a framework.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```javascript
|
|
8
|
+
* import { PhoneAuthClient } from '@glideidentity/web-client-sdk/vanilla';
|
|
9
|
+
*
|
|
10
|
+
* const client = new PhoneAuthClient({ debug: true });
|
|
11
|
+
*
|
|
12
|
+
* document.getElementById('auth-btn').addEventListener('click', async () => {
|
|
13
|
+
* try {
|
|
14
|
+
* const result = await client.authenticate({
|
|
15
|
+
* use_case: 'VerifyPhoneNumber',
|
|
16
|
+
* phone_number: '+14155551234'
|
|
17
|
+
* });
|
|
18
|
+
* console.log('Verified:', result.verified);
|
|
19
|
+
* } catch (error) {
|
|
20
|
+
* console.error('Auth failed:', error);
|
|
21
|
+
* }
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
// Re-export everything from client
|
|
26
|
+
export { PhoneAuthClient } from '../client/phone-auth-client';
|
|
27
|
+
// Re-export constants
|
|
28
|
+
export { USE_CASE, AUTHENTICATION_STRATEGY } from '../core/types';
|
|
29
|
+
export { ERROR_CODES, isAuthError, createAuthError } from '../core/errors';
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vue Adapter for Phone Authentication SDK.
|
|
3
|
+
*
|
|
4
|
+
* Provides a Vue composable that wraps PhoneAuthClient with Vue reactivity.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```vue
|
|
8
|
+
* <script setup>
|
|
9
|
+
* import { usePhoneAuth } from '@glideidentity/web-client-sdk/vue';
|
|
10
|
+
*
|
|
11
|
+
* const { authenticate, isLoading, error, result } = usePhoneAuth({ debug: true });
|
|
12
|
+
*
|
|
13
|
+
* const handleClick = async () => {
|
|
14
|
+
* try {
|
|
15
|
+
* const result = await authenticate({
|
|
16
|
+
* use_case: 'VerifyPhoneNumber',
|
|
17
|
+
* phone_number: '+14155551234'
|
|
18
|
+
* });
|
|
19
|
+
* console.log('Verified:', result.verified);
|
|
20
|
+
* } catch (err) {
|
|
21
|
+
* // Error is also in `error` ref
|
|
22
|
+
* }
|
|
23
|
+
* };
|
|
24
|
+
* </script>
|
|
25
|
+
*
|
|
26
|
+
* <template>
|
|
27
|
+
* <button @click="handleClick" :disabled="isLoading">
|
|
28
|
+
* {{ isLoading ? 'Verifying...' : 'Verify Phone' }}
|
|
29
|
+
* </button>
|
|
30
|
+
* </template>
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
import { ref, computed } from 'vue';
|
|
34
|
+
import { PhoneAuthClient } from '../client/phone-auth-client';
|
|
35
|
+
// Re-export PhoneAuthClient and core types/constants for convenience
|
|
36
|
+
export { PhoneAuthClient } from '../client/phone-auth-client';
|
|
37
|
+
export { USE_CASE, AUTHENTICATION_STRATEGY } from '../core/types';
|
|
38
|
+
export { ERROR_CODES, isAuthError, createAuthError } from '../core/errors';
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// COMPOSABLE
|
|
41
|
+
// ============================================================================
|
|
42
|
+
/**
|
|
43
|
+
* Vue composable for phone authentication.
|
|
44
|
+
*/
|
|
45
|
+
export function usePhoneAuth(config) {
|
|
46
|
+
// Create client once
|
|
47
|
+
const client = new PhoneAuthClient(config);
|
|
48
|
+
// Reactive state
|
|
49
|
+
const isLoading = ref(false);
|
|
50
|
+
const error = ref(null);
|
|
51
|
+
const result = ref(null);
|
|
52
|
+
const step = ref('idle');
|
|
53
|
+
// Computed
|
|
54
|
+
const isSupported = computed(() => client.isSupported());
|
|
55
|
+
/**
|
|
56
|
+
* High-level authentication.
|
|
57
|
+
*/
|
|
58
|
+
async function authenticate(request, options) {
|
|
59
|
+
isLoading.value = true;
|
|
60
|
+
error.value = null;
|
|
61
|
+
step.value = 'preparing';
|
|
62
|
+
try {
|
|
63
|
+
const authResult = await client.authenticate(request, options);
|
|
64
|
+
result.value = authResult;
|
|
65
|
+
step.value = 'complete';
|
|
66
|
+
return authResult;
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
error.value = err;
|
|
70
|
+
step.value = 'error';
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
isLoading.value = false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Granular: Prepare.
|
|
79
|
+
*/
|
|
80
|
+
async function prepare(request) {
|
|
81
|
+
isLoading.value = true;
|
|
82
|
+
error.value = null;
|
|
83
|
+
step.value = 'preparing';
|
|
84
|
+
try {
|
|
85
|
+
const result = await client.prepare(request);
|
|
86
|
+
step.value = 'idle'; // Reset step on success (prepare is just first step)
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
error.value = err;
|
|
91
|
+
step.value = 'error';
|
|
92
|
+
throw err;
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
isLoading.value = false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Granular: Invoke.
|
|
100
|
+
*/
|
|
101
|
+
async function invokeSecurePrompt(prepared, options) {
|
|
102
|
+
step.value = 'invoking';
|
|
103
|
+
try {
|
|
104
|
+
return await client.invokeSecurePrompt(prepared, options);
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
error.value = err;
|
|
108
|
+
step.value = 'error';
|
|
109
|
+
throw err;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Granular: Get phone number.
|
|
114
|
+
*/
|
|
115
|
+
async function getPhoneNumber(credential, session) {
|
|
116
|
+
isLoading.value = true;
|
|
117
|
+
step.value = 'processing';
|
|
118
|
+
try {
|
|
119
|
+
const authResult = await client.getPhoneNumber(credential, session);
|
|
120
|
+
result.value = authResult;
|
|
121
|
+
step.value = 'complete';
|
|
122
|
+
return authResult;
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
error.value = err;
|
|
126
|
+
step.value = 'error';
|
|
127
|
+
throw err;
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
isLoading.value = false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Granular: Verify phone number.
|
|
135
|
+
*/
|
|
136
|
+
async function verifyPhoneNumber(credential, session) {
|
|
137
|
+
isLoading.value = true;
|
|
138
|
+
step.value = 'processing';
|
|
139
|
+
try {
|
|
140
|
+
const authResult = await client.verifyPhoneNumber(credential, session);
|
|
141
|
+
result.value = authResult;
|
|
142
|
+
step.value = 'complete';
|
|
143
|
+
return authResult;
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
error.value = err;
|
|
147
|
+
step.value = 'error';
|
|
148
|
+
throw err;
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
isLoading.value = false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Reset state.
|
|
156
|
+
*/
|
|
157
|
+
function reset() {
|
|
158
|
+
isLoading.value = false;
|
|
159
|
+
error.value = null;
|
|
160
|
+
result.value = null;
|
|
161
|
+
step.value = 'idle';
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
isLoading,
|
|
165
|
+
error,
|
|
166
|
+
result,
|
|
167
|
+
step,
|
|
168
|
+
isSupported,
|
|
169
|
+
authenticate,
|
|
170
|
+
prepare,
|
|
171
|
+
invokeSecurePrompt,
|
|
172
|
+
getPhoneNumber,
|
|
173
|
+
verifyPhoneNumber,
|
|
174
|
+
reset,
|
|
175
|
+
client,
|
|
176
|
+
};
|
|
177
|
+
}
|
package/dist/esm/browser.js
CHANGED
|
@@ -1,11 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Browser-specific entry point for vanilla JavaScript usage.
|
|
3
|
+
* This is bundled via webpack and exposed as `window.GlideWebClientSDK`.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```html
|
|
7
|
+
* <script src="/sdk/web-client-sdk.min.js"></script>
|
|
8
|
+
* <script>
|
|
9
|
+
* const client = new GlideWebClientSDK.PhoneAuthClient({ debug: true });
|
|
10
|
+
* const result = await client.authenticate({
|
|
11
|
+
* use_case: GlideWebClientSDK.USE_CASE.VERIFY_PHONE_NUMBER,
|
|
12
|
+
* phone_number: '+14155551234'
|
|
13
|
+
* });
|
|
14
|
+
* </script>
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
// Main client
|
|
18
|
+
export { PhoneAuthClient } from './client/phone-auth-client';
|
|
19
|
+
// Constants
|
|
20
|
+
export { USE_CASE, AUTHENTICATION_STRATEGY } from './core/types';
|
|
21
|
+
// Error codes
|
|
22
|
+
export { ERROR_CODES } from './core/errors';
|
|
23
|
+
// Type guards
|
|
24
|
+
export { isInvokeResult, isAuthCredential, isTS43Strategy, isLinkStrategy, isDesktopStrategy, isCancellable, isTS43Data, isLinkData, isDesktopData, isGetPhoneNumberResponse, isVerifyPhoneNumberResponse, isErrorResponse, } from './core/type-guards';
|
|
25
|
+
// Error utilities
|
|
26
|
+
export { isAuthError, isClientError, isRetryableError, getUserMessage, createAuthError, } from './core/errors';
|
|
27
|
+
// Validators
|
|
28
|
+
export { validatePhoneNumber, validatePlmn, } from './core/validators';
|
|
29
|
+
// UI components
|
|
30
|
+
export { AuthModal, createQRCodeDataFromDesktop } from './ui/modal';
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Client for Phone Authentication SDK.
|
|
3
|
+
*
|
|
4
|
+
* Provides a default fetch-based implementation with:
|
|
5
|
+
* - Timeout support
|
|
6
|
+
* - Static and dynamic headers
|
|
7
|
+
* - Error parsing using Core utilities
|
|
8
|
+
*/
|
|
9
|
+
import { createAuthError, parseBackendError, ERROR_CODES } from '../core/errors';
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// DEFAULT HTTP CLIENT
|
|
12
|
+
// ============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* Create a default fetch-based HTTP client.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const http = createHttpClient({
|
|
19
|
+
* timeout: 30000,
|
|
20
|
+
* headers: {
|
|
21
|
+
* common: { 'X-Client-Version': '2.0.0' },
|
|
22
|
+
* prepare: { 'X-Prepare-Only': 'true' }
|
|
23
|
+
* },
|
|
24
|
+
* dynamicHeaders: async (ctx) => {
|
|
25
|
+
* const token = await getAuthToken();
|
|
26
|
+
* return { 'Authorization': `Bearer ${token}` };
|
|
27
|
+
* }
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export function createHttpClient(config = {}) {
|
|
32
|
+
const { timeout = 30000, headers = {}, dynamicHeaders } = config;
|
|
33
|
+
/**
|
|
34
|
+
* Build headers for a request.
|
|
35
|
+
*/
|
|
36
|
+
async function buildHeaders(context, additionalHeaders) {
|
|
37
|
+
const result = {
|
|
38
|
+
'Content-Type': 'application/json',
|
|
39
|
+
};
|
|
40
|
+
// Add common headers
|
|
41
|
+
if (headers.common) {
|
|
42
|
+
Object.assign(result, headers.common);
|
|
43
|
+
}
|
|
44
|
+
// Add endpoint-specific headers
|
|
45
|
+
const endpointHeaders = headers[context.endpoint];
|
|
46
|
+
if (endpointHeaders && typeof endpointHeaders === 'object') {
|
|
47
|
+
Object.assign(result, endpointHeaders);
|
|
48
|
+
}
|
|
49
|
+
// Add dynamic headers
|
|
50
|
+
if (dynamicHeaders) {
|
|
51
|
+
const dynamic = await dynamicHeaders(context);
|
|
52
|
+
Object.assign(result, dynamic);
|
|
53
|
+
}
|
|
54
|
+
// Add additional headers from options
|
|
55
|
+
if (additionalHeaders) {
|
|
56
|
+
Object.assign(result, additionalHeaders);
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Make a fetch request with timeout.
|
|
62
|
+
*/
|
|
63
|
+
async function fetchWithTimeout(url, init, requestTimeout, signal) {
|
|
64
|
+
const controller = new AbortController();
|
|
65
|
+
const timeoutId = setTimeout(() => controller.abort(), requestTimeout);
|
|
66
|
+
// If external signal provided, link it to our controller
|
|
67
|
+
// Store handler reference so we can remove it later (prevent memory leak)
|
|
68
|
+
const abortHandler = signal ? () => controller.abort() : null;
|
|
69
|
+
if (signal && abortHandler) {
|
|
70
|
+
signal.addEventListener('abort', abortHandler);
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
const response = await fetch(url, {
|
|
74
|
+
...init,
|
|
75
|
+
signal: controller.signal,
|
|
76
|
+
});
|
|
77
|
+
return response;
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
// Check if it's a timeout (AbortError from our controller)
|
|
81
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
82
|
+
// Check if it was our timeout or external abort
|
|
83
|
+
if (signal?.aborted) {
|
|
84
|
+
throw createAuthError(ERROR_CODES.CANCELLED, 'Request was cancelled');
|
|
85
|
+
}
|
|
86
|
+
throw createAuthError(ERROR_CODES.TIMEOUT, 'Request timed out');
|
|
87
|
+
}
|
|
88
|
+
// Network error
|
|
89
|
+
throw createAuthError(ERROR_CODES.NETWORK_ERROR, error instanceof Error ? error.message : 'Network request failed');
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
clearTimeout(timeoutId);
|
|
93
|
+
// Clean up event listener to prevent memory leak
|
|
94
|
+
if (signal && abortHandler) {
|
|
95
|
+
signal.removeEventListener('abort', abortHandler);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Parse response and handle errors.
|
|
101
|
+
*/
|
|
102
|
+
async function parseResponse(response) {
|
|
103
|
+
// Try to parse JSON
|
|
104
|
+
let data;
|
|
105
|
+
try {
|
|
106
|
+
data = await response.json();
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// If JSON parsing fails and response is not ok, throw generic error
|
|
110
|
+
if (!response.ok) {
|
|
111
|
+
throw createAuthError(ERROR_CODES.INVALID_RESPONSE, `Request failed with status ${response.status}`);
|
|
112
|
+
}
|
|
113
|
+
throw createAuthError(ERROR_CODES.INVALID_RESPONSE, 'Failed to parse response');
|
|
114
|
+
}
|
|
115
|
+
// If response is not ok, parse as error
|
|
116
|
+
if (!response.ok) {
|
|
117
|
+
throw parseBackendError({ ...data, status: response.status });
|
|
118
|
+
}
|
|
119
|
+
return data;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Determine endpoint type from URL for header context.
|
|
123
|
+
*/
|
|
124
|
+
function getEndpointType(url) {
|
|
125
|
+
if (url.includes('/prepare'))
|
|
126
|
+
return 'prepare';
|
|
127
|
+
if (url.includes('/process') || url.includes('/get-phone') || url.includes('/verify-phone'))
|
|
128
|
+
return 'process';
|
|
129
|
+
if (url.includes('/status'))
|
|
130
|
+
return 'polling';
|
|
131
|
+
return 'prepare'; // Default
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
async post(url, body, options) {
|
|
135
|
+
const endpointType = getEndpointType(url);
|
|
136
|
+
const requestHeaders = await buildHeaders({ endpoint: endpointType, method: 'POST' }, options?.headers);
|
|
137
|
+
const response = await fetchWithTimeout(url, {
|
|
138
|
+
method: 'POST',
|
|
139
|
+
headers: requestHeaders,
|
|
140
|
+
body: JSON.stringify(body),
|
|
141
|
+
}, options?.timeout || timeout, options?.signal);
|
|
142
|
+
return parseResponse(response);
|
|
143
|
+
},
|
|
144
|
+
async get(url, options) {
|
|
145
|
+
const endpointType = getEndpointType(url);
|
|
146
|
+
const requestHeaders = await buildHeaders({ endpoint: endpointType, method: 'GET' }, options?.headers);
|
|
147
|
+
// Remove Content-Type for GET requests
|
|
148
|
+
delete requestHeaders['Content-Type'];
|
|
149
|
+
const response = await fetchWithTimeout(url, {
|
|
150
|
+
method: 'GET',
|
|
151
|
+
headers: requestHeaders,
|
|
152
|
+
}, options?.timeout || timeout, options?.signal);
|
|
153
|
+
return parseResponse(response);
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client module exports.
|
|
3
|
+
*/
|
|
4
|
+
// Main Client
|
|
5
|
+
export { PhoneAuthClient } from './phone-auth-client';
|
|
6
|
+
// HTTP Client
|
|
7
|
+
export { createHttpClient } from './http';
|
|
8
|
+
// Logger
|
|
9
|
+
export { createLogger, createNoopLogger } from './logger';
|
|
10
|
+
// Strategies (internal, but exported for advanced use)
|
|
11
|
+
export { createPollingHandler } from './strategies/polling';
|