glide-web-client-sdk
TypeScript icon, indicating that this package has built-in type declarations

3.0.2 • Public • Published

Glide Web Client SDK

The official web SDK for integrating Glide's carrier-grade phone verification into your web applications. Supports React, Vue, Angular, and vanilla JavaScript/TypeScript.

Features

  • 🚀 Instant Verification: Direct carrier verification without SMS
  • 🔐 Fraud Resistant: Can't be intercepted or spoofed like SMS codes
  • Real-time Progress: Track verification steps with detailed state management
  • 🌐 Framework Support: React, Vue 3, Angular, and vanilla JS/TS
  • 🛡️ Type Safe: Full TypeScript support with comprehensive types
  • 🎯 Developer Friendly: Clear error messages and browser compatibility checks

Table of Contents

Installation

npm install glide-web-client-sdk

or

yarn add glide-web-client-sdk

Quick Start

Vue 3

<template>
  <div>
    <button @click="getNumber" :disabled="isLoading">
      {{ isLoading ? 'Verifying...' : 'Get My Phone Number' }}
    </button>
    
    <!-- Progress indicator -->
    <div v-if="isLoading">
      {{ currentStep }}: 
      <span v-if="currentStep === 'requesting'">Preparing request...</span>
      <span v-if="currentStep === 'authenticating'">Waiting for carrier approval...</span>
      <span v-if="currentStep === 'processing'">Processing response...</span>
    </div>
    
    <div v-if="error" class="error">
      {{ error.message }}
    </div>
    
    <div v-if="result" class="success">
      Phone: {{ result.phoneNumber }}
    </div>
  </div>
</template>

<script setup>
import { usePhoneAuth } from 'glide-web-client-sdk/vue'

const {
  getPhoneNumber,
  verifyPhoneNumber,
  isLoading,
  error,
  result,
  currentStep,
  isSupported
} = usePhoneAuth({
  endpoints: {
    prepare: '/api/phone-auth/prepare',
    process: '/api/phone-auth/process'
  }
})

const getNumber = async () => {
  try {
    await getPhoneNumber()
  } catch (err) {
    console.error('Verification failed:', err)
  }
}
</script>

React

import { usePhoneAuth } from 'glide-web-client-sdk/react'

function PhoneVerification() {
  const {
    getPhoneNumber,
    verifyPhoneNumber,
    isLoading,
    error,
    result,
    currentStep,
    isSupported
  } = usePhoneAuth({
    endpoints: {
      prepare: '/api/phone-auth/prepare',
      process: '/api/phone-auth/process'
    }
  })

  const handleGetNumber = async () => {
    try {
      await getPhoneNumber()
    } catch (err) {
      console.error('Verification failed:', err)
    }
  }

  const handleVerifyNumber = async (phoneNumber) => {
    try {
      await verifyPhoneNumber(phoneNumber)
    } catch (err) {
      console.error('Verification failed:', err)
    }
  }

  if (!isSupported) {
    return <div>Browser not supported. Please enable Digital Credentials API.</div>
  }

  return (
    <div>
      <button onClick={handleGetNumber} disabled={isLoading}>
        {isLoading ? `${currentStep}...` : 'Get My Phone Number'}
      </button>
      
      {error && <div className="error">{error.message}</div>}
      {result && <div className="success">Phone: {result.phoneNumber}</div>}
    </div>
  )
}

Angular

import { Component } from '@angular/core'
import { PhoneAuthService } from 'glide-web-client-sdk/angular'

@Component({
  selector: 'app-phone-verification',
  template: `
    <button (click)="getNumber()" [disabled]="isLoading$ | async">
      {{ (isLoading$ | async) ? (currentStep$ | async) : 'Get My Phone Number' }}
    </button>
    
    <div *ngIf="error$ | async as error" class="error">
      {{ error.message }}
    </div>
    
    <div *ngIf="result$ | async as result" class="success">
      Phone: {{ result.phoneNumber }}
    </div>
  `
})
export class PhoneVerificationComponent {
  isLoading$ = this.phoneAuth.isLoading$
  error$ = this.phoneAuth.error$
  result$ = this.phoneAuth.result$
  currentStep$ = this.phoneAuth.currentStep$

  constructor(private phoneAuth: PhoneAuthService) {
    // Configure the service
    this.phoneAuth.configure({
      endpoints: {
        prepare: '/api/phone-auth/prepare',
        process: '/api/phone-auth/process'
      }
    })
  }

  async getNumber() {
    try {
      await this.phoneAuth.getPhoneNumber()
    } catch (err) {
      console.error('Verification failed:', err)
    }
  }
}

Vanilla JavaScript/TypeScript

import { PhoneAuthManager } from 'glide-web-client-sdk/vanilla'

// Initialize the manager
const phoneAuth = new PhoneAuthManager({
  endpoints: {
    prepare: '/api/phone-auth/prepare',
    process: '/api/phone-auth/process'
  }
})

// Subscribe to state changes
phoneAuth.subscribe((state) => {
  console.log('Current state:', state)
  
  if (state.isLoading) {
    document.getElementById('status').textContent = state.currentStep
  }
  
  if (state.error) {
    document.getElementById('error').textContent = state.error.message
  }
  
  if (state.result) {
    document.getElementById('result').textContent = state.result.phoneNumber
  }
})

// Verify phone
async function getPhoneNumber() {
  try {
    await phoneAuth.getPhoneNumber()
  } catch (err) {
    console.error('Verification failed:', err)
  }
}

Error Handling

The SDK provides comprehensive error handling with typed errors and user-friendly messages.

Error Types

interface AuthError {
  code: string
  message: string
  details?: any
  browserError?: {
    name: string
    message: string
    stack?: string
    code?: number
  }
  context?: {
    step: 'prepare' | 'prompt' | 'process'
    timestamp: string
    userAgent?: string
    url?: string
  }
}

Common Error Codes

Code Description User Action
BROWSER_NOT_SUPPORTED Digital Credentials API not available Enable Chrome flag
USER_DENIED User cancelled authentication Try again
CARRIER_NOT_ELIGIBLE Carrier doesn't support verification Use alternative method
SESSION_NOT_FOUND Session expired Retry verification
RATE_LIMIT_EXCEEDED Too many attempts Wait before retrying
NETWORK_ERROR Network connection failed Check connection

Error Handling Example

import { 
  isPhoneAuthError, 
  isUserError, 
  getUserMessage,
  PhoneAuthErrorCode 
} from 'glide-web-client-sdk/vue' // or /react, /angular, /vanilla

try {
  await verifyPhoneNumber('+1234567890')
} catch (error) {
  if (isPhoneAuthError(error)) {
    // Check for specific error types
    if (error.code === PhoneAuthErrorCode.CARRIER_NOT_ELIGIBLE) {
      console.log('Carrier not supported')
    } else if (error.code === PhoneAuthErrorCode.USER_DENIED) {
      console.log('User cancelled')
    } else if (isUserError(error)) {
      // Show user-friendly message
      alert(getUserMessage(error))
    }
    
    // Log error details for debugging
    console.error('Error details:', {
      code: error.code,
      step: error.context?.step,
      browserError: error.browserError
    })
  }
}

Browser Support

The SDK requires the Digital Credentials API, which is currently available in:

  • ✅ Chrome 117+ (with flag enabled)
  • ✅ Edge 117+ (with flag enabled)
  • ❌ Firefox (not supported)
  • ❌ Safari (not supported)

Enabling Browser Support

  1. Open Chrome or Edge
  2. Navigate to:
    • Chrome: chrome://flags/#web-identity-digital-credentials
    • Edge: edge://flags/#web-identity-digital-credentials
  3. Set the flag to "Enabled" (not "Default")
  4. Click "Relaunch" to restart the browser

Checking Browser Support

import { usePhoneAuth } from 'glide-web-client-sdk/vue'

const { isSupported } = usePhoneAuth()

if (!isSupported) {
  console.log('Browser not supported. Please enable Digital Credentials API.')
}

API Reference

Configuration

interface AuthConfig {
  endpoints?: {
    prepare?: string  // Default: '/api/phone-auth/prepare'
    process?: string  // Default: '/api/phone-auth/process'
  }
  timeout?: number    // Default: 30000 (30 seconds)
  debug?: boolean     // Default: false
}

Methods

getPhoneNumber(options?)

Retrieves the user's phone number from their device.

const result = await getPhoneNumber({
  consentData: {
    consentText: 'I agree to the terms',
    policyLink: 'https://example.com/privacy',
    policyText: 'Privacy Policy'
  }
})

verifyPhoneNumber(phoneNumber, options?)

Verifies ownership of a specific phone number.

const result = await verifyPhoneNumber('+1234567890', {
  consentData: {
    consentText: 'I agree to verify my phone',
    policyLink: 'https://example.com/terms'
  }
})

State Properties

Property Type Description
isLoading boolean Whether verification is in progress
error AuthError | null Current error if any
result PhoneAuthResult | null Verification result
currentStep 'idle' | 'requesting' | 'authenticating' | 'processing' | 'complete' Current verification step
isSupported boolean Whether browser supports the API

Advanced Usage

Low-Level API Access

For advanced use cases, you can access the low-level PhoneAuthClient methods:

import { PhoneAuthClient } from 'glide-web-client-sdk'

const client = new PhoneAuthClient({
  endpoints: {
    prepare: '/api/phone-auth/prepare',
    process: '/api/phone-auth/process'
  }
})

// Manual flow
const request = await client.preparePhoneRequest({ 
  useCase: 'VerifyPhoneNumber', 
  phoneNumber: '+1234567890' 
})

const credential = await client.invokeSecurePrompt(request)

const result = await client.processPhoneResponse(
  credential, 
  request.session, 
  { useCase: 'VerifyPhoneNumber' }
)

Backend Integration

The SDK requires two backend endpoints. You can implement these using the Glide Node SDK or your own backend.

Using Glide Node SDK

import { GlideClient } from '@glideidentity/sdk'

const glide = new GlideClient({
  clientId: process.env.GLIDE_CLIENT_ID,
  clientSecret: process.env.GLIDE_CLIENT_SECRET,
  redirectUri: process.env.GLIDE_REDIRECT_URI,
})

// Prepare endpoint
app.post('/api/phone-auth/prepare', async (req, res) => {
  try {
    const request = await glide.magicAuth.phoneNumbers.generateRequest({
      useCase: req.body.use_case,
      phoneNumber: req.body.phone_number,
      consentData: req.body.consent_data
    })
    res.json(request)
  } catch (error) {
    res.status(error.status || 500).json({ error: error.message })
  }
})

// Process endpoint
app.post('/api/phone-auth/process', async (req, res) => {
  try {
    const result = await glide.magicAuth.phoneNumbers.authenticate({
      session: req.body.session,
      response: req.body.response
    })
    res.json(result)
  } catch (error) {
    res.status(error.status || 500).json({ error: error.message })
  }
})

Testing

Unit Tests

npm test

Integration Testing

For testing in development, you can use the Glide demo server:

const { getPhoneNumber } = usePhoneAuth({
  endpoints: {
    prepare: 'https://checkout-demo-server.glideidentity.dev/generate-get-request',
    process: 'https://checkout-demo-server.glideidentity.dev/processCredential'
  }
})

Contributing

We welcome contributions! Please see our Contributing Guide for details.

License

MIT © Glide Identity

Support

Package Sidebar

Install

npm i glide-web-client-sdk

Weekly Downloads

13

Version

3.0.2

License

none

Unpacked Size

481 kB

Total Files

92

Last publish

Collaborators

  • glideapi