All files / src/utils fingerprint.ts

100% Statements 114/114
100% Branches 27/27
100% Functions 5/5
100% Lines 114/114

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 1151x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7x 7x 7x 1x 1x 1x 6x 7x 5x 5x 5x 5x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7x 7x 1x 1x 1x 1x 4x 4x 4x 4x 3x 4x 4x 1x 1x 1x 1x 1x 1x 8x 8x 8x 1x 1x 7x 7x 7x 7x 7x 7x 7x 8x 2x 2x 2x 2x 8x 1x 1x 1x 1x 1x 1x 1x 1x 1x 6x 1x 1x 5x 5x 5x 5x 5x 1x 6x 1x 1x 4x 6x 1x 1x 1x 1x 3x 3x 3x 6x 2x 2x 2x 2x 6x  
/**
 * Fingerprint utility wrapper for bundled fingerprint-datapicker-lib.js
 *
 * The fingerprint script is bundled directly into the SDK during build time.
 * No external network calls are made - the script is included in the bundle.
 */
 
// Type definition for the global __gateway object
declare global {
  interface Window {
    __gateway?: {
      getFingerprintString: () => string;
    };
  }
}
 
/**
 * Waits for DOM to be ready
 */
function waitForDOMReady(): Promise<void> {
  return new Promise((resolve) => {
    if (typeof document === 'undefined') {
      resolve();
      return;
    }
 
    if (document.readyState === 'complete' || document.readyState === 'interactive') {
      // DOM is already ready, wait a tick to ensure scripts have executed
      setTimeout(resolve, 0);
      return;
    }
 
    // Wait for DOMContentLoaded
    document.addEventListener(
      'DOMContentLoaded',
      () => {
        // Wait a tick to ensure all scripts have executed
        setTimeout(resolve, 0);
      },
      { once: true }
    );
  });
}
 
/**
 * Checks if the fingerprint script is available
 */
function isFingerprintAvailable(): boolean {
  return (
    typeof window !== 'undefined' &&
    typeof window.__gateway !== 'undefined' &&
    typeof window.__gateway.getFingerprintString === 'function'
  );
}
 
/**
 * Gets the fingerprint string using the bundled fingerprint library
 * @returns Promise that resolves to the fingerprint string
 * @throws Error if fingerprint script fails to initialize or execute
 */
export async function getFingerprintAsync(): Promise<string> {
  // Check if we're in a browser environment
  if (typeof window === 'undefined') {
    throw new Error('getFingerprint requires a browser environment');
  }
 
  // Wait for DOM to be ready (fingerprint script initializes in docReady callback)
  await waitForDOMReady();
 
  // Get fingerprint string
  try {
    return window.__gateway!.getFingerprintString();
  } catch (error) {
    throw new Error(
      `Failed to get fingerprint: ${error instanceof Error ? error.message : 'Unknown error'}`
    );
  }
}
 
/**
 * Synchronous version - works if bundled script is already initialized and DOM is ready
 * Note: This will throw an error if DOM is not ready or script hasn't initialized yet.
 * For reliable usage, prefer getFingerprint() which handles async initialization.
 * @returns The fingerprint string
 * @throws Error if fingerprint script is not initialized or DOM is not ready
 */
export function getFingerprint(): string {
  if (typeof window === 'undefined') {
    throw new Error('getFingerprintSync requires a browser environment');
  }
 
  // Check if DOM is ready
  if (
    typeof document !== 'undefined' &&
    document.readyState !== 'complete' &&
    document.readyState !== 'interactive'
  ) {
    throw new Error('DOM is not ready. Use getFingerprint() instead or wait for DOMContentLoaded.');
  }
 
  if (!isFingerprintAvailable()) {
    throw new Error(
      'Fingerprint script is not initialized. Use getFingerprint() instead or ensure DOM is ready.'
    );
  }
 
  try {
    return window.__gateway!.getFingerprintString();
  } catch (error) {
    throw new Error(
      `Failed to get fingerprint: ${error instanceof Error ? error.message : 'Unknown error'}`
    );
  }
}