UNPKG

@pos-360/touch-id

Version:

The Touch ID API is used to interface with fingerprint scanning hardware.

291 lines (210 loc) 9.57 kB
# @pos-360/touch-id A Node.js native module to interface with SecuGen fingerprint readers on Windows. This module provides an intuitive API for interacting with the SecuGen Hamster SDK (sgfplib.dll). ## Features - **Device Management:** Open, close, and retrieve device information (image dimensions, contrast, brightness, etc.) from connected SecuGen fingerprint readers. - **Capture & Template Creation:** Capture fingerprint images and create fingerprint templates for matching. - **Template Matching:** Compare two fingerprint templates to determine a match. - **Auto-On Mode:** Enable convenient "auto-on" mode to capture fingerprints as soon as a finger is placed on the reader. - **Asynchronous Operations:** Fingerprint capture and template creation are asynchronous, allowing for non-blocking behavior. ## Installation ```bash npm install @pos-360/touch-id ``` ## Usage ### Import the module ```typescript import { SecugenHandler, AutoOnEvent, SecugenErrors } from '@pos-360/touch-id'; ``` ### Create a new instance of the SecugenHandler class ```typescript const secugen = new SecugenHandler(); ``` ### Open the device ```typescript const openResult = secugen.open(); if (openResult.ok === false) { console.error(openResult.message); process.exit(1); } console.log("Opened device."); ``` ### Get device information ```typescript const deviceInfoResult = secugen.getDeviceInfo(); if (deviceInfoResult.ok === false) { console.error(deviceInfoResult.message); } else { console.log("Device info:", deviceInfoResult); } ``` ### Capture a fingerprint and create a template ```typescript const captureResult = await secugen.captureAndCreateTemplate(); if (captureResult.ok === false) { console.error(captureResult.message); } else { console.log("Captured template:", captureResult); } ``` ### Compare two templates ```typescript const compareResult = await secugen.compareTemplates(template1, template2); if (compareResult.ok === false) { console.error(compareResult.message); } else { console.log("Templates match:", compareResult.isMatch); } ``` ### Start auto-on mode ```typescript const startAutoOnResult = await secugen.startAutoOn(); if (startAutoOnResult.ok === false) { console.error(startAutoOnResult.message); } else { console.log("Started auto-on mode."); secugen.subscribeToAutoOnEvent(AutoOnEvent.Capture, (payload) => { if (payload.ok === false) { console.error(payload.message); } else { console.log("Auto-on capture:", payload); } }); } ``` ### Stop auto-on mode ```typescript const stopAutoOnResult = secugen.stopAutoOn(); if (stopAutoOnResult.ok === false) { console.error(stopAutoOnResult.message); } else { console.log("Stopped auto-on mode."); } ``` ### Capture a fingerprint from auto-on mode ```typescript const captureResult = await secugen.captureFromAutoOn(5_000); if (captureResult.ok === false) { if (captureResult.code === SecugenErrors.CAPTURE_TIMEOUT) { console.log("Capture timeout."); } else { console.error(captureResult.message); } } else { console.log("Captured from auto-on:", captureResult); } ``` ### Cancel capture from auto-on mode ```typescript const cancelResult = await secugen.cancelCaptureFromAutoOn(); if (cancelResult.ok === false) { console.error(cancelResult.message); } else { console.log("Cancelled capture."); } ``` ### Close the device ```typescript const closeResult = await secugen.close(); if (closeResult.ok === false) { console.error(closeResult.message); } else { console.log("Closed device."); } ``` ## Error handling The `SecugenHandler` methods return objects with the following structure: ```typescript type GoodResult = { ok: true; // ... other properties }; type BadResult = { ok: false; code: SecugenErrorCodes; message: SecugenErrorMessages; }; ``` You can use the `ok` property to check if the operation was successful. If it was not, you can use the `code` and `message` properties to get more information about the error. The `SecugenErrors` object contains a list of all possible error codes and messages. ## Example ```typescript import { SecugenHandler, AutoOnEvent, SecugenErrors, } from "@pos-360/touch-id"; const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); (async () => { const secugen = new SecugenHandler(); const openResult = secugen.open(); if (openResult.ok === false) { console.error(openResult.message); process.exit(1); } console.log("Opened device."); try { await secugen.startAutoOn(); console.log("Started auto-on mode."); const autoTemplateData = await secugen.captureFromAutoOn(); if (autoTemplateData.ok === false) { if (autoTemplateData.code === SecugenErrors.CAPTURE_TIMEOUT) { console.log("Capture timeout."); } else { console.error(autoTemplateData.message); } } else { console.log("Auto-on template data:", autoTemplateData); } } catch (err) { console.error(err); } finally { await secugen.close(); console.log("Closed device."); } })(); ``` ## API Reference ### `SecugenHandler` Class - `new SecugenHandler()`: Creates a new `SecugenHandler` instance. #### Methods - `open(): DefaultResponse`: Opens the connected SecuGen device. Returns a `DefaultResponse` object indicating success or failure. - `close(): Promise<DefaultResponse>`: Closes the SecuGen device. Returns a Promise that resolves with a `DefaultResponse` object indicating success or failure. - `getDeviceInfo(): DeviceInfoResult`: Returns a `DeviceInfoResult` object with device information including `DeviceID`, `ImageWidth`, `ImageHeight`, `Contrast`, `Brightness`, `Gain`, and `ImageDPI`, or an error object if the device is not opened. - `captureAndCreateTemplate(): Promise<CaptureResult>`: Asynchronously captures a fingerprint image and creates a template. Returns a Promise that resolves with a `CaptureResult` object containing the raw image data and the base64-encoded template, or an error object if the device is not opened or auto-on mode is active. - `startAutoOn(): Promise<DefaultResponse>`: Starts the "auto-on" mode. The provided callback function will be invoked with events when fingers are placed/removed from the reader and when captures are made. Returns a Promise that resolves with a `DefaultResponse` object indicating success or failure. - `stopAutoOn(): DefaultResponse`: Stops the "auto-on" mode. Returns a `DefaultResponse` object indicating success or failure. - `captureFromAutoOn(timeout?: number): Promise<CaptureResult>`: Asynchronously captures a fingerprint in "auto-on" mode. Returns a Promise that resolves with a `CaptureResult` object containing the raw image data and the base64-encoded template, or an error object if auto-on mode is not active or a timeout occurs. An optional `timeout` parameter in milliseconds can be provided. - `cancelCaptureFromAutoOn(): Promise<DefaultResponse>`: Cancels the capture operation initiated by `captureFromAutoOn`. Returns a Promise that resolves with a `DefaultResponse` object indicating success or failure. - `compareTemplates(template1: string, template2: string): CompareResult`: Compares two base64-encoded fingerprint templates. Returns a `CompareResult` object indicating whether a match was found, or an error object if the device is not opened. - `isAutoOnActive(): boolean`: Returns a boolean indicating whether "auto-on" mode is active. - `subscribeToAutoOnEvent<T extends AutoOnEvent>(event: T, listener: (payload: AutoOnEventPayload<T>) => void): DefaultResponse`: Subscribes to an event in auto-on mode. Returns a `DefaultResponse` object indicating success or failure. Available events are `fingerOn`, `fingerOff`, `capture`, and `error`. - `unsubscribeFromAutoOnEvent<T extends AutoOnEvent>(event: T, listener: (payload: AutoOnEventPayload<T>) => void): DefaultResponse`: Unsubscribes from an event in auto-on mode. Returns a `DefaultResponse` object indicating success or failure. ## Troubleshooting ### Module not initialized If you get the error `Module not initialized` or the method calls return `{ ok: false, code: 'FAILURE_TO_INIT', message: 'Module not initialized' }`, then make sure that you have called `open()` before any other methods and that the SecuGen device is connected to your computer. ### Device not found If you get the error `Device not found`, make sure that the SecuGen device is connected to your computer and that the driver is installed. ### USB Bandwidth is not sufficient If you get the error `USB Bandwidth is not sufficient for image transfer`, try using a different USB port or a USB hub with its own power supply. ## Building ### Troubleshooting on Windows If you have a problem building on Windows due to a `openssl != ''` error, make the following edit to `<node-gyp path>/gyp/pylib/gyp/input.py`: ``` diff --git a/gyp/pylib/gyp/input.py b/gyp/pylib/gyp/input.py index 354958b..bb982eb 100644 --- a/gyp/pylib/gyp/input.py +++ b/gyp/pylib/gyp/input.py @@ -1190,7 +1190,7 @@ def EvalSingleCondition(cond_expr, true_dict, false_dict, phase, variables, buil else: ast_code = compile(cond_expr_expanded, "<string>", "eval") cached_conditions_asts[cond_expr_expanded] = ast_code - env = {"__builtins__": {}, "v": StrictVersion} + env = {"__builtins__": {"openssl_fips": ""}, "v": StrictVersion} if eval(ast_code, env, variables): return true_dict return false_dict ``` ## License MIT