@pos-360/touch-id
Version:
The Touch ID API is used to interface with fingerprint scanning hardware.
330 lines (324 loc) • 13.1 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('node:path'), require('node:events'), require('node:process')) :
typeof define === 'function' && define.amd ? define(['exports', 'node:path', 'node:events', 'node:process'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@pos-360/touch-id"] = {}, global.path, global.node_events, global.process));
})(this, (function (exports, path, node_events, process) { 'use strict';
const SecugenErrors = {
ERROR_NONE: "Function Success",
ERROR_CREATION_FAILED: "Failed to create SGFPM instance",
ERROR_FUNCTION_FAILED: "Function failed to call for unknown reason",
ERROR_INVALID_PARAM: "Invalid parameter",
ERROR_NOT_USED: "Function is not used or not supported",
ERROR_DLLLOAD_FAILED: "Failed to load sgfplib.dll. Make sure that sgfplib.dll is located at node's path",
ERROR_DLLLOAD_FAILED_DRV: "Cannot load device driver",
ERROR_DLLLOAD_FAILED_ALGO: "Cannot load matching module",
ERROR_NO_LONGER_SUPPORTED: "Function is no longer supported",
ERROR_DLLLOAD_FAILED_WSQ: "Sgwsqlib.dll not loaded",
ERROR_SYSLOAD_FAILED: "Failed to load driver sys file",
ERROR_INITIALIZE_FAILED: "Failed to initialize device",
ERROR_LINE_DROPPED: "Image data loss occurred during capture",
ERROR_TIME_OUT: "Timeout occurred during capture",
ERROR_DEVICE_NOT_FOUND: "Device not found",
ERROR_WRONG_IMAGE: "Wrong image - not recognized as a fingerprint image",
ERROR_LACK_OF_BANDWIDTH: "USB Bandwidth is not sufficient for image transfer",
ERROR_DEV_ALREADY_OPEN: "Device is already in use",
ERROR_GETSN_FAILED: "Failed to get serial number of the device",
ERROR_UNSUPPORTED_DEV: "Cannot determine device type",
ERROR_FAKE_FINGER: "Fake finger detected",
ERROR_FAKE_INITIALIZED: "Initialization of fake module failed",
ERROR_FEAT_NUMBER: "Not enough minutiae features",
ERROR_INVALID_TEMPLATE_TYPE: "Template type is invalid",
ERROR_INVALID_TEMPLATE1: "1st template is invalid",
ERROR_INVALID_TEMPLATE2: "2nd template is invalid",
ERROR_EXTRACT_FAIL: "Failed to extract template",
ERROR_MATCH_FAIL: "Cannot find matched template",
ERROR_LICENSE_LOAD: "Failed to load license",
ERROR_LICENSE_KEY: "Invalid license key",
ERROR_LICENSE_EXPIRED: "License expired",
ERROR_NO_IMAGE: "Invalid image",
// Custom errors
AUTO_ON_ACTIVE: "Auto-On is currently active. Please turn off before executing this function.",
AUTO_ON_NOT_ACTIVE: "Auto-On is not active. Please turn on before executing this function.",
DEVICE_NOT_OPENED: "Device is not opened",
CAPTURE_LOW_QUALITY: "Capture image quality is too low",
// Binding-specific errors
CAPTURE_TIMEOUT: "Capture timeout",
CAPTURE_CANCELLED: "Capture was cancelled",
MISC_ERROR: "Miscellaneous error",
FAILURE_TO_INIT: "Module not initialized",
};
const UnsupportedPlatformPayload = {
ok: false,
code: "FAILURE_TO_INIT",
message: "Module not initialized",
};
const AutoOnEvent = {
FingerOn: "fingerOn",
FingerOff: "fingerOff",
Capture: "capture",
SystemError: "error",
};
const bindings = require("node-gyp-build")(path.join(__dirname, ".."));
const SecugenHandlerModule = bindings;
let _moduleInstance;
let _emitter = new node_events.EventEmitter();
let _autoOnCapturePromise = null;
let _autoOnCapturePromiseResolve = null;
const _onceListeners = new Map();
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
process.on("SIGINT", () => {
if (_moduleInstance) {
_moduleInstance.closeDevice();
}
process.exit();
});
class SecugenHandler {
constructor() {
// if not on windows, do not initialize module
if (process.platform !== "win32") {
return;
}
if (_moduleInstance) {
return;
}
try {
_moduleInstance = SecugenHandlerModule;
}
catch (err) {
console.log(err);
}
}
/**
* @description
* Start the auto-on mode of the fingerprint scanner, thus allowing the
* scanner to capture fingerprints automatically and emit events.
*/
async startAutoOn() {
if (!_moduleInstance) {
return UnsupportedPlatformPayload;
}
_moduleInstance.startAutoOn((event, ...args) => {
_emitter.emit(event, ...args);
});
await delay(100);
return { ok: true };
}
/**
* @description
* Stop the auto-on mode of the fingerprint scanner, thus stopping the
* scanner from capturing fingerprints automatically and emitting events.
*/
stopAutoOn() {
if (!_moduleInstance) {
return UnsupportedPlatformPayload;
}
_moduleInstance.stopAutoOn();
return { ok: true };
}
/**
* @description
* Subscribe to an auto-on event emitted by the fingerprint scanner.
*/
subscribeToAutoOnEvent(event, listener) {
if (!_moduleInstance) {
return UnsupportedPlatformPayload;
}
_emitter.on(event, listener);
return { ok: true };
}
/**
* @description
* Unsubscribe from an auto-on event emitted by the fingerprint
* scanner.
*/
unsubscribeFromAutoOnEvent(event, listener) {
if (!_moduleInstance) {
return UnsupportedPlatformPayload;
}
_emitter.off(event, listener);
return { ok: true };
}
/**
* @description
* Get the device information of the fingerprint scanner.
*/
getDeviceInfo() {
if (!_moduleInstance) {
return UnsupportedPlatformPayload;
}
try {
return _moduleInstance.getDeviceInfo();
}
catch (err) {
const parsedError = JSON.parse(err);
return {
ok: false,
code: parsedError.code,
message: parsedError.message,
};
}
}
/**
* @description
* Open the fingerprint scanner device.
*/
open() {
if (!_moduleInstance) {
return UnsupportedPlatformPayload;
}
return _moduleInstance.openDevice();
}
/**
* @description
* Capture and create a template from the fingerprint scanner.
*
* @param {number} timeout The timeout in milliseconds.
*/
async captureAndCreateTemplate(timeout) {
if (!_moduleInstance) {
return UnsupportedPlatformPayload;
}
return new Promise((resolve, reject) => {
try {
_moduleInstance.captureAndCreateTemplate((err, data) => {
if (err) {
resolve(err);
}
resolve(data);
}, timeout);
}
catch (err) {
reject({
ok: false,
code: "MISC_ERROR",
message: err,
});
}
});
}
/**
* @description
* Capture a fingerprint from the auto-on mode of the fingerprint scanner.
* This method will return a promise that resolves with the captured
* fingerprint data. Accepts an optional timeout parameter that will reject
* the promise if the timeout is reached.
*
* @param {number} [timeout] The timeout in milliseconds.
*/
async captureFromAutoOn(timeout) {
if (!_moduleInstance) {
return UnsupportedPlatformPayload;
}
if (_moduleInstance.isAutoOnActive() === false) {
return {
ok: false,
code: "AUTO_ON_NOT_ACTIVE",
message: SecugenErrors.AUTO_ON_NOT_ACTIVE,
};
}
if (_autoOnCapturePromise != null) {
return _autoOnCapturePromise;
}
const promise = new Promise((resolve) => {
_autoOnCapturePromiseResolve = resolve;
const autoOnCaptureListener = (data) => {
this.clearAutoOnCapturePromise();
resolve(data);
};
const autoOnErrorListener = (error) => {
this.clearAutoOnCapturePromise();
resolve({
ok: false,
code: "MISC_ERROR",
message: error,
});
};
_onceListeners.set(AutoOnEvent.Capture, autoOnCaptureListener);
_onceListeners.set(AutoOnEvent.SystemError, autoOnErrorListener);
_emitter.once(AutoOnEvent.Capture, autoOnCaptureListener);
_emitter.once(AutoOnEvent.SystemError, autoOnErrorListener);
if (timeout) {
setTimeout(() => {
this.clearAutoOnCapturePromise();
resolve({
ok: false,
code: "CAPTURE_TIMEOUT",
message: SecugenErrors.CAPTURE_TIMEOUT,
});
}, timeout);
}
});
_autoOnCapturePromise = promise;
return promise;
}
/**
* @description
* Cancel the capture from the auto-on mode of the fingerprint scanner.
* This method will reject the promise returned by the `captureFromAutoOn`
*/
async cancelCaptureFromAutoOn() {
if (!_moduleInstance) {
return UnsupportedPlatformPayload;
}
if (_autoOnCapturePromise != null) {
_autoOnCapturePromiseResolve?.({
ok: false,
code: "CAPTURE_CANCELLED",
message: SecugenErrors.CAPTURE_CANCELLED,
});
this.clearAutoOnCapturePromise();
}
return { ok: true };
}
/**
* @description
* Close the fingerprint scanner device. This method will also clear the
* promise returned by the `captureFromAutoOn` method.
*/
async close() {
if (!_moduleInstance) {
return UnsupportedPlatformPayload;
}
if (_autoOnCapturePromise != null) {
_autoOnCapturePromiseResolve?.({
ok: false,
code: "CAPTURE_CANCELLED",
message: SecugenErrors.CAPTURE_CANCELLED,
});
this.clearAutoOnCapturePromise();
}
return await delay(1000).then(() => {
return _moduleInstance.closeDevice();
});
}
/**
* @description
* Compare two fingerprint templates and return the result.
* @param template1 - Base64 encoded template 1
* @param template2 - Base64 encoded template 2
*/
compareTemplates(template1, template2) {
if (!_moduleInstance) {
return UnsupportedPlatformPayload;
}
return _moduleInstance.compareTemplates(template1, template2);
}
clearAutoOnCapturePromise() {
_autoOnCapturePromise = null;
_autoOnCapturePromiseResolve = null;
if (_onceListeners.get(AutoOnEvent.Capture) != null) {
_emitter.off(AutoOnEvent.Capture, _onceListeners.get(AutoOnEvent.Capture));
_onceListeners.delete(AutoOnEvent.Capture);
}
if (_onceListeners.get(AutoOnEvent.SystemError) != null) {
_emitter.off(AutoOnEvent.SystemError, _onceListeners.get(AutoOnEvent.SystemError));
_onceListeners.delete(AutoOnEvent.SystemError);
}
}
}
exports.AutoOnEvent = AutoOnEvent;
exports.SecugenErrors = SecugenErrors;
exports.UnsupportedPlatformPayload = UnsupportedPlatformPayload;
exports.default = SecugenHandler;
Object.defineProperty(exports, '__esModule', { value: true });
}));