Skip to content

legalesign/ls-viewer-demo

Repository files navigation

Legalesign Document Viewer Demo

A React TypeScript project demonstrating the Legalesign Document Viewer component with secure token management.

Additional details and description available here: https://docs.legalesign.com/components/document-viewer#installation

Authentication Options

This demo provides two authentication methods to obtain access tokens for the Document Viewer. Choose the method that best fits your use case:

Option A: API Key Authentication (server.js)

Best for: Simple integrations, server-to-server communication, API-first applications

  • Direct authentication using your Legalesign API key
  • Minimal setup and configuration
  • Single credential to manage
  • Ideal for backend services and automation

Option B: AWS Cognito SRP Authentication (server-cognito.js)

Best for: Enterprise applications, user-based authentication, AWS-integrated systems

  • Secure Remote Password (SRP) protocol
  • User-based authentication with username/password
  • JWT token-based authorization
  • Integrates with AWS Cognito User Pool
  • Perfect for users that already have a session open
  • Supports MFA and advanced user management

Both methods are production-ready and secure. The browser never sees your credentials—only short-lived access tokens.

Architecture

This demo uses a client-server architecture to securely handle authentication:

┌─────────────┐         ┌─────────────┐         ┌──────────────────┐
│   Browser   │────────▶│   Server    │────────▶│  Legalesign API  │
│  (React)    │         │  (Express)  │         │   (GraphQL)      │
└─────────────┘         └─────────────┘         └──────────────────┘
     │                        │                          │
     │  1. Request token      │                          │
     │───────────────────────▶│                          │
     │                        │  2. GraphQL mutation     │
     │                        │     with API key / SRP   │
     │                        │─────────────────────────▶│
     │                        │                          │
     │                        │  3. Access token         │
     │                        │◀─────────────────────────│
     │  4. Return token       │                          │
     │◀───────────────────────│                          │
     │                        │                          │
     │  5. Use token with Document Viewer                │
     │──────────────────────────────────────────────────▶│

Why This Architecture?

Security: Your credentials (API key or SRP password) never leave the server. The browser only receives short-lived access tokens.

Server Side

Option A: API Key (server.js)

  • Stores API key in environment variables
  • Makes GraphQL mutation with API key in Authorization header
  • Returns only the access token to browser

Option B: Cognito SRP (server-cognito.js)

  • Stores Cognito credentials in environment variables
  • Authenticates with AWS Cognito using SRP protocol
  • Obtains JWT token from Cognito User Pool
  • Uses JWT token in Authorization header for GraphQL requests
  • Returns only the access token to browser

Client Side (App.tsx)

  • Fetches access token from the backend server on mount
  • Passes the token to the LsDocumentViewer component
  • No sensitive credentials in the browser

Setup

1. Install dependencies

npm install

2. Choose and configure your authentication method

You must choose either API Key authentication or Cognito authentication.

Option A: API Key Authentication (Simpler)

  1. Copy the API key environment template:

    cp .env.example .env
  2. Edit .env and add your Legalesign API key:

    LEGALESIGN_API_KEY=your_api_key_here
  3. Where to get API key: Log into your Legalesign account → Settings → API → Generate API key

Option B: Cognito SRP Authentication (Enterprise)

  1. Copy the Cognito environment template:

    cp .env.example .env
  2. Edit .env and add your AWS Cognito credentials (the first two fields are LEGALESIGN_CLIENT_ID & LEGALESIGN_USER_POOL_ID):

    LEGALESIGN_USERNAME=your_username_here
    LEGALESIGN_PASSWORD=your_password_here
    LEGALESIGN_CLIENT_ID=CONTACTUS
    LEGALESIGN_USER_POOL_ID=CONTACTUS
  3. Where to get Cognito credentials: AWS Console

3. Start the backend server

Start the server that matches your chosen authentication method:

For API Key authentication:

npm run server

For Cognito SRP authentication:

npm run server:cognito

The server will start on http://localhost:3001

4. Start the React app

In another terminal:

npm run dev

The app will start on http://localhost:5173

How It Works

Option A: API Key Authentication Flow

  1. Browser requests token: When the React app loads, it calls POST /api/get-token on the Express server

  2. Server makes GraphQL mutation: The Express server uses the API key to request an access token from Legalesign's GraphQL endpoint:

    mutation {
      generateComponentToken(input: { component: LS_DOCUMENT_VIEWER }) {

        token         expiresIn        } }

With headers:

POST https://graphql.uk.legalesign.com/graphql Content-Type: application/json Authorization: <your_api_key>


3. **Legalesign returns token**: The GraphQL API validates the API key and returns:
```json
{
  "data": {
    "generateComponentToken": {
      "token": "eyJraWQiOiJBTkJIeT...",
      "expiresIn": 3600
    }
  }
}
  1. Server forwards token: The Express server sends only the access token to the browser

  2. Browser uses token: The React app passes the token to LsDocumentViewer, which uses it to authenticate GraphQL requests

Option B: Cognito SRP Authentication Flow

  1. Browser requests token: When the React app loads, it calls POST /api/get-token on the Express server

  2. Server authenticates with Cognito: The Express server uses AWS Legalesign SRP (Secure Remote Password) protocol:

    • Initiates authentication with username/password
    • Performs cryptographic challenge-response (SRP)
    • Receives a token from the Legalesign platform.
  3. Legalesign returns token: The GraphQL API validates the JWT and returns the access token

  4. Server forwards token: The Express server sends only the access token to the browser

  5. Browser uses token: The React app passes the token to LsDocumentViewer

Configuration

The viewer is configured with:

  • Template ID: yourTemplateId
  • Mode: editor (full-featured template editing)
  • Endpoint: https://graphql.uk.legalesign.com/graphql

Available Modes

Change the mode prop in src/App.tsx:

Security Best Practices

DO:

  • Store credentials in environment variables (never in code)
  • Use server-side token generation (never expose credentials to browser)
  • Add .env to .gitignore
  • Implement token refresh logic for production
  • Use HTTPS in production
  • Choose the authentication method that fits your security requirements

DON'T:

  • Hardcode API keys or passwords in source code
  • Expose credentials to the browser
  • Commit .env files to version control
  • Use this exact setup in production without additional security measures

Which Authentication Method Should I Use?

Use API Key if:

  • You're building a server-to-server integration
  • You want the simplest setup
  • You don't need user-level authentication
  • You're building internal tools or automation
  • You've generated an API key for your account
  • Want to use restricted keys for specific Legalesign components

Use Legalesign SRP / Username & Password if:

  • You want to quickly demo a component, or you're a developer wanting the quickest first project
  • You're building a user-facing application
  • You need user-level authentication and authorization
  • You've integrated your ID/user accounts with the Legalesign platform
  • You need MFA or advanced security features
  • You want to track which user performed which action

Production Considerations

Server-Side Technology Choice

Important: The Express/Node.js server in this demo is just one example. Any server-side technology can call the Legalesign GraphQL API as long as it can:

  • Make HTTPS requests
  • Set HTTP headers (Authorization, Content-Type)
  • Parse JSON responses

Common alternatives:

  • Python (Flask, FastAPI, Django) - Most popular alternative to Node.js
  • Java (Spring Boot) - Enterprise standard
  • C# (.NET Core) - Microsoft ecosystem
  • Go - High-performance services
  • Ruby (Rails, Sinatra) - Rapid development
  • PHP (Laravel) - Web hosting standard

The authentication logic is identical regardless of language—make a GraphQL mutation with your credentials in the Authorization header.

Deploying to AWS Amplify

Important: This Express server setup is designed for local development only. AWS Amplify Hosting serves static files and cannot run the Express server.

For production deployment on AWS Amplify, choose one of these options:

Option 1: AWS Lambda + API Gateway (Recommended)

Create a Lambda function to handle the token exchange:

// amplify/functions/get-token/handler.ts
export const handler = async (event) => {
  const response = await fetch('https://graphql.uk.legalesign.com/graphql', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': process.env.LEGALESIGN_API_KEY,
    },
    body: JSON.stringify({
      query: `
        mutation {
          generateComponentToken(input: { component: LS_DOCUMENT_VIEWER }) {
            token
            expiresIn
          }
        }
      `,
    }),
  });
  
  const data = await response.json();
  return {
    statusCode: 200,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ 
      accessToken: data.data.generateComponentToken.token,
      expiresIn: data.data.generateComponentToken.expiresIn
    }),
  };
};

Deploy the Lambda function and API Gateway endpoint, then update your React app to call the Lambda endpoint instead of http://localhost:3001.

Option 2: Separate Backend Service

Deploy the Express server to a separate AWS service:

  • AWS Elastic Beanstalk - Managed platform for Node.js applications
  • AWS ECS/Fargate - Containerized deployment
  • AWS App Runner - Simplified container deployment

Update the React app's fetch URL to point to your deployed backend.

Option 3: Amplify Gen 2 with SSR

If using Next.js or a similar SSR framework, use Amplify Gen 2 which supports server-side rendering:

// app/api/get-token/route.ts (Next.js)
export async function POST() {
  const response = await fetch('https://graphql.uk.legalesign.com/graphql', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': process.env.LEGALESIGN_API_KEY!,
    },
    body: JSON.stringify({
      query: `
        mutation {
          generateComponentToken(input: { component: LS_DOCUMENT_VIEWER }) {
            token
            expiresIn
          }
        }
      `,
    }),
  });
  
  const data = await response.json();
  return Response.json({ 
    accessToken: data.data.generateComponentToken.token,
    expiresIn: data.data.generateComponentToken.expiresIn
  });
}

Other Production Considerations

For production deployments:

  • Implement token caching and refresh logic
  • Add rate limiting to the token endpoint
  • Use environment-specific configuration
  • Implement proper error handling and logging
  • Add authentication/authorization for your backend API
  • Use HTTPS for all communications

Documentation

About

A demonstration of using the Editor component with server-side sample.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors