Single Page App SDK
Universal JavaScript SDK for modern single-page applications.
Installation
npm install glide-web-client-sdk
# or
yarn add glide-web-client-sdk
Quick Start
import { PhoneAuthClient } from 'glide-web-client-sdk';
const client = new PhoneAuthClient({
endpoints: {
prepare: '/api/phone-auth/prepare',
process: '/api/phone-auth/process'
},
debug: true, // Enable debug logging
onCrossDeviceDetected: () => {
// Handle QR code display for cross-device flow
console.log('Cross-device flow detected');
},
onRetryAttempt: (attempt, maxAttempts) => {
// Handle retry attempts
console.log(`Retry ${attempt}/${maxAttempts}`);
}
});
// Verify phone number
async function verifyPhone() {
try {
const result = await client.verifyPhoneNumberComplete('+14155551234', {
consent_data: {
consent_text: 'I agree to verify my phone number',
policy_link: 'https://example.com/privacy',
policy_text: 'Privacy Policy'
}
});
if (result.verified) {
console.log('Phone verified successfully!');
}
} catch (error) {
console.error('Verification failed:', error);
}
}
// Get phone number from device
async function getPhoneNumber() {
try {
const result = await client.getPhoneNumberComplete({
plmn: { mcc: '310', mnc: '260' }, // Optional: specify carrier
consent_data: {
consent_text: 'I agree to share my phone number',
policy_link: 'https://example.com/privacy',
policy_text: 'Privacy Policy'
}
});
console.log('Phone number:', result.phone_number);
} catch (error) {
console.error('Failed to get phone number:', error);
}
}
Configuration Options
interface PhoneAuthClientConfig {
endpoints: {
prepare: string; // Your backend prepare endpoint
process: string; // Your backend process endpoint
};
debug?: boolean; // Enable debug logging
maxRetries?: number; // Maximum retry attempts (default: 3)
retryDelay?: number; // Delay between retries in ms (default: 1000)
onCrossDeviceDetected?: () => void; // Callback for cross-device flow
onRetryAttempt?: (attempt: number, maxAttempts: number) => void; // Retry callback
}
API Methods
High-Level Methods
verifyPhoneNumberComplete(phoneNumber, options?)
Complete flow to verify phone ownership.
const result = await client.verifyPhoneNumberComplete('+14155551234', {
consent_data: {
consent_text: 'I agree to verify my phone number',
policy_link: 'https://example.com/privacy',
policy_text: 'Privacy Policy'
}
});
// Returns: { verified: boolean, phone_number: string }
getPhoneNumberComplete(options?)
Complete flow to retrieve phone number from device.
const result = await client.getPhoneNumberComplete({
plmn: { mcc: '310', mnc: '260' },
consent_data: {
consent_text: 'I agree to share my phone number',
policy_link: 'https://example.com/privacy',
policy_text: 'Privacy Policy'
}
});
// Returns: { phone_number: string }
Granular Control Methods
For advanced use cases, you can control each step of the authentication flow:
// Step 1: Prepare the request
const prepareResult = await client.preparePhoneRequest({
use_case: 'VerifyPhoneNumber',
phone_number: '+14155551234',
consent_data: { /* ... */ }
});
// Step 2: Invoke browser prompt
const credential = await client.invokeSecurePrompt(prepareResult.request);
// Step 3: Process the credential
const verifyResult = await client.verifyPhoneNumberCredential(
credential,
prepareResult.session
);
Error Handling
try {
const result = await client.verifyPhoneNumberComplete(phoneNumber);
} catch (error) {
if (error.code === 'CARRIER_NOT_ELIGIBLE') {
// Handle unsupported carrier
console.log('Your carrier is not supported');
} else if (error.code === 'PHONE_NUMBER_MISMATCH') {
// Handle phone number mismatch
console.log('Phone number does not match device');
} else {
// Handle other errors
console.error('Verification failed:', error.message);
}
}
Browser Support
- Chrome 119+
- Edge 119+
- Safari (Coming Soon)
- Firefox (Coming Soon)
Backend Integration
Your backend needs to handle two endpoints:
Prepare Endpoint
app.post('/api/phone-auth/prepare', async (req, res) => {
const response = await glide.magicAuth.prepare(req.body);
res.json(response);
});
Process Endpoint
app.post('/api/phone-auth/process', async (req, res) => {
if (req.body.use_case === 'VerifyPhoneNumber') {
const response = await glide.magicAuth.verifyPhoneNumber(req.body);
res.json(response);
} else {
const response = await glide.magicAuth.getPhoneNumber(req.body);
res.json(response);
}
});