SecuGen Connect Developer Guide
Migration · WebAPI

WebAPI Migration Guide

For browser apps that were written against the legacy SecuGen WebAPI and now need to talk to SecuGen Connect — either exclusively, or alongside the legacy WebAPI during migration.

Components

Port map

Base URLRole
https://localhost:8000Legacy WebAPI (plaintext-style HTTPS deployment)
https://localhost:8443Legacy WebAPI (TLS deployment variant)
http://127.0.0.1:4499SecuGen Connect bridge on mainstream Windows/Linux installs
http://127.0.0.1:4499/v1/compat/*Bridge endpoints that return legacy-shaped JSON

The bridge prefers 4499 and may fall back through 4498-4494 if that default port is busy. There is no transport-level redirect from 84434499; the span is performed at the application layer by either (a) rewriting the URL, (b) the JS shim, or (c) the server-side compat endpoints on the bridge itself.

Design choices

Adopted

Explicitly deferred

Integration steps (Connect-only)

  1. Load the shim scripts before the existing legacy app script.
  2. Call SecuGenWebAPIShim.init(...) once at startup.
  3. Keep existing capture / match callbacks as-is.
  4. Verify CORS and browser local/private network access for http://127.0.0.1:4499.
<script src="secugen-webapi-shim.js"></script>
<script src="jsgfplib-compat.js"></script>
<script>
  SecuGenWebAPIShim.init({
    connectUrl: "http://127.0.0.1:4499",
    legacyUrl:  "https://localhost:8443",   // or :8000 for plaintext deployments
    autoIntercept: true
  });
</script>

Running Connect and Legacy WebAPI side-by-side

SecuGen Connect and the legacy WebAPI bind different ports and coexist on the same machine without conflict. A single page can target both during migration.

Option A — Runtime detection with fallback

Probe Connect first; fall back to the legacy WebAPI if the bridge is not reachable. Pick the base URL once and reuse it everywhere — capture / match response shapes are identical in both branches.

async function detectBiometricEndpoint() {
  // Prefer Connect (newer, cross-platform, licensed).
  try {
    const r = await fetch("http://127.0.0.1:4499/v1/health", { cache:"no-store" });
    if (r.ok) {
      const body = await r.json();
      if (body && body.ok) {
        return { kind:"connect", base:"http://127.0.0.1:4499/v1/compat" };
      }
    }
  } catch (_) { /* bridge not reachable */ }

  // Fallback: legacy WebAPI. OPTIONS returns 200 or 405 even without a reader attached.
  for (const base of ["https://localhost:8443","https://localhost:8000"]) {
    try {
      const r = await fetch(base + "/SGIFPCapture", { method:"OPTIONS" });
      if (r.ok || r.status === 405) return { kind:"legacy", base };
    } catch (_) { /* not running */ }
  }
  return { kind:"none", base:null };
}

const ep = await detectBiometricEndpoint();
const captureUri = ep.base + "/SGIFPCapture"; // same path on both branches

ep.kind is only needed for telemetry (a "Using Connect" badge) and for hiding WebAPI-only fields the bridge does not return (ImageBMP, ImageWSQ, NFIQ, …).

Option B — Conditional shim activation (zero-diff for demo code)

Wrap SecuGenWebAPIShim.init in the same probe. If Connect is up, the shim intercepts XHR / fetch and redirects all legacy URLs to :4499. If Connect is down, the shim never activates and the demo hits the real WebAPI untouched.

<script src="secugen-webapi-shim.js"></script>
<script src="jsgfplib-compat.js"></script>
<script>
  (async () => {
    try {
      const r = await fetch("http://127.0.0.1:4499/v1/health", { cache:"no-store" });
      if (r.ok) {
        SecuGenWebAPIShim.init({
          connectUrl: "http://127.0.0.1:4499",
          legacyUrl:  "https://localhost:8443",  // shim matches by prefix
          autoIntercept: true
        });
      }
    } catch (_) {
      // Connect not reachable — leave XHR/fetch untouched; demo keeps hitting 8443.
    }
  })();
</script>
<!-- existing demo code runs unchanged below -->

This is the recommended pattern when the demo HTML is hard to change but Connect availability is mixed across users.

Option C — Explicit user toggle

Expose a "Use SecuGen Connect / Use legacy WebAPI" setting persisted in localStorage. On page load, pick the base URL from that setting and call SecuGenWebAPIShim.init when the Connect branch is selected. Useful for QA and user-driven migration.

Caveats when both endpoints are reachable

ConcernWhat breaksFix
TLS cert trustOnly the legacy WebAPI endpoint should require self-signed cert acceptance in the mainstream Connect path.Use Connect over loopback HTTP unless an enterprise/macOS HTTPS fallback is explicitly configured.
Local network accessSecure browser contexts may require local/private network permission before calling loopback HTTP.Keep CORS, Origin, session, nonce, rate-limit, and PNA/LNA handling enabled.
CORS origin allowlistConnect enforces allowed origins; legacy WebAPI is more permissive.Add the demo's origin to Connect's CORS config.
Session tokenConnect requires a Bearer session token; WebAPI does not.SecuGenWebAPIShim.init({ sessionAutoManage:true }) handles it; for Option A, add a POST /v1/session/start on the Connect branch.
Missing response fieldsNFIQ, ImageBMP, ImageWSQ, ImageDataBase64, BMPBase64, WSQImage* return null on Connect.If the demo displays these, hide / fallback when ep.kind === "connect".
Error-code valuesConnect error codes overlap but do not fully match legacy WebAPI codes.Use the shim mapping table; do not pattern-match raw integers.

Recommended migration sequence

  1. Today. Ship Option B (conditional shim) so the demo works on any mix of installed runtimes without per-call branching.
  2. Connect coverage is high. Drop the localhost:8443 fallback and move to Option A with a single base URL.
  3. Legacy retirement. Remove the shim and call the canonical @secugen/connect-sdk directly.

Validation checklist

  1. Capture returns ErrorCode: 0 and TemplateBase64.
  2. Match returns ErrorCode: 0 and a non-zero MatchingScore.
  3. URL rewrite confirms the legacy host is replaced by the Connect host.
  4. Failure path: with the bridge stopped, the legacy error callback fires.
  5. Timeout path aborts in-flight request when AbortController is available and returns timeout error to the legacy callback.
  6. Invalid bridgeBaseUrl values (non-HTTP(S), empty host) fall back safely to http://127.0.0.1:4499.
  7. Dual-support. With both Connect and legacy WebAPI running, Option B activates the shim on Connect availability and leaves the demo on :8443 / :8000 when Connect is stopped.
  8. Transport fallback. If an enterprise/macOS HTTPS fallback is enabled, repeat Option A / B against that configured base URL.