Skip to content

Latest commit

 

History

History
184 lines (153 loc) · 5.11 KB

File metadata and controls

184 lines (153 loc) · 5.11 KB

Frontend Integration

This guide explains how to integrate the Contact Us API with your frontend website. It provides complete code examples for the three-step authentication and submission process.

Overview

The API uses a three-step process:

  1. Request a token when the form page loads
  2. Generate a signature server-side (keeps signing secret secure)
  3. Submit the contact form with token and signature

Step 1: Request Token on Page Load

When the contact form page loads, request a token from the API:

async function loadContactForm() {
  const response = await fetch('https://api.example.com/api/token', {
    method: 'GET',
    headers: {
      'Origin': 'https://www.example.com'
    }
  });
  
  const data = await response.json();
  return data.token;
}

Step 2: Generate Signature

Request a signature from the server. This keeps the signing secret secure on the backend.

async function generateSignature(name, email, message, token) {
  const timestamp = Math.floor(Date.now() / 1000);
  
  const response = await fetch('https://api.example.com/api/signature', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Origin': 'https://www.example.com'
    },
    body: JSON.stringify({
      name,
      email,
      message,
      token,
      timestamp
    })
  });
  
  const data = await response.json();
  return data.signature;
}

Step 3: Submit Form

Submit the contact form with all required data:

async function submitContactForm(name, email, message, token) {
  const timestamp = Math.floor(Date.now() / 1000);
  
  // Generate signature server-side (keeps signing secret secure)
  const signature = await generateSignature(name, email, message, token);
  
  const response = await fetch('https://api.example.com/api/contact', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Origin': 'https://www.example.com'
    },
    body: JSON.stringify({
      name,
      email,
      message,
      token,
      signature,
      timestamp
    })
  });
  
  return await response.json();
}

Complete Example

Here's a complete example that handles the entire flow:

async function handleContactFormSubmit(formData) {
  try {
    // Step 1: Get token
    const tokenResponse = await fetch('https://api.example.com/api/token', {
      method: 'GET',
      headers: { 'Origin': 'https://www.example.com' }
    });
    const { token } = await tokenResponse.json();
    
    // Step 2: Generate signature
    const timestamp = Math.floor(Date.now() / 1000);
    const signatureResponse = await fetch('https://api.example.com/api/signature', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Origin': 'https://www.example.com'
      },
      body: JSON.stringify({
        name: formData.name,
        email: formData.email,
        message: formData.message,
        token,
        timestamp
      })
    });
    const { signature } = await signatureResponse.json();
    
    // Step 3: Submit form
    const submitResponse = await fetch('https://api.example.com/api/contact', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Origin': 'https://www.example.com'
      },
      body: JSON.stringify({
        name: formData.name,
        email: formData.email,
        message: formData.message,
        token,
        signature,
        timestamp
      })
    });
    
    return await submitResponse.json();
  } catch (error) {
    console.error('Error submitting form:', error);
    throw error;
  }
}

Important Notes

  1. Origin Header: Always include the Origin header matching one of your allowed CORS origins (configured via CONTACT_API_CORS_ALLOWED_ORIGINS). See Configuration Guide for details.
  2. Token Expiration: Tokens expire after 5 minutes (default, configurable via CONTACT_API_SECURITY_TOKEN_EXPIRY_SECONDS). Request a new token if the user takes too long to submit.
  3. Error Handling: Always handle errors appropriately and provide user feedback.
  4. HTTPS: Use HTTPS in production to protect tokens and signatures in transit.
  5. Rate Limiting: Be aware of rate limits - tokens are limited per IP, submissions are limited per IP and origin. See Configuration Guide for rate limiting details.

Error Handling

The API returns standard HTTP status codes:

  • 200: Success
  • 400: Invalid request data or missing fields
  • 401: Invalid or expired token
  • 403: Invalid signature or CORS violation
  • 429: Rate limit exceeded (check Retry-After header)
  • 500: Internal server error

Example error handling:

try {
  const result = await submitContactForm(formData);
  if (result.status === 'success') {
    // Show success message
  } else {
    // Handle error
    console.error('Submission failed:', result.message);
  }
} catch (error) {
  if (error.response?.status === 429) {
    const retryAfter = error.response.headers.get('Retry-After');
    console.error(`Rate limited. Retry after ${retryAfter} seconds`);
  } else {
    console.error('Error:', error);
  }
}