From 751afdef37ae4de33175691ae96fbebd9ca1da97 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Mon, 25 Mar 2019 11:32:16 -0700 Subject: [PATCH] Module dependency cleanup. --- meshcentral.js | 38 +- meshuser.js | 29 +- package - Copy.json | 57 + package.json | 7 +- reinstall-modules.bat | 1 + views/default-min.handlebars | 13941 +++++++++++++++++++++++++++- views/login-min.handlebars | 1288 ++- views/login-mobile-min.handlebars | 1218 ++- views/login-mobile.handlebars | 58 +- views/login.handlebars | 39 +- webserver.js | 2 +- 11 files changed, 16630 insertions(+), 48 deletions(-) create mode 100644 package - Copy.json create mode 100644 reinstall-modules.bat diff --git a/meshcentral.js b/meshcentral.js index eb1040ef..a6cb8f4c 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -1606,23 +1606,16 @@ function InstallModules(modules, func) { // Check if a module is present and install it if missing var InstallModuleChildProcess = null; function InstallModule(modulename, func, tag1, tag2) { - try { - var module = require(modulename); - } catch (e) { - console.log('Installing ' + modulename + '...'); - var child_process = require('child_process'); - - // Looks like we need to keep a global reference to the child process object for this to work correctly. - InstallModuleChildProcess = child_process.exec('npm install ' + modulename + ' --no-optional --save', { maxBuffer: 512000, timeout: 10000 }, function (error, stdout, stderr) { - InstallModuleChildProcess = null; - if (error != null) { console.log('ERROR: Unable to install missing package \'' + modulename + '\', make sure npm is installed: ' + error); process.exit(); return; } - func(tag1, tag2); - return; - }); + console.log('Installing ' + modulename + '...'); + var child_process = require('child_process'); + // Looks like we need to keep a global reference to the child process object for this to work correctly. + InstallModuleChildProcess = child_process.exec('npm install ' + modulename + ' --no-optional --save', { maxBuffer: 512000, timeout: 10000 }, function (error, stdout, stderr) { + InstallModuleChildProcess = null; + if (error != null) { console.log('ERROR: Unable to install missing package \'' + modulename + '\', make sure npm is installed: ' + error); process.exit(); return; } + func(tag1, tag2); return; - } - func(tag1, tag2); + }); } // Detect CTRL-C on Linux and stop nicely @@ -1640,10 +1633,12 @@ function mainStart(args) { var config = getConfig(false); if (config == null) { process.exit(); } - // Check is Windows SSPI will be used + // Check is Windows SSPI and YubiKey OTP will be used var sspi = false; var allsspi = true; - if (require('os').platform() == 'win32') { for (var i in config.domains) { if (config.domains[i].auth == 'sspi') { sspi = true; } else { allsspi = false; } } } + var yubikey = false; + if (require('os').platform() == 'win32') { for (var i in config.domains) { if (config.domains[i].auth == 'sspi') { sspi = true; } else { allsspi = false; } } } else { allsspi = false; } + for (var i in config.domains) { if (config.domains[i].yubikey != null) { yubikey = true; } } // Build the list of required modules var modules = ['ws', 'nedb', 'https', 'yauzl', 'xmldom', 'express', 'archiver', 'multiparty', 'node-forge', 'express-ws', 'compression', 'body-parser', 'connect-redis', 'express-handlebars']; @@ -1651,6 +1646,7 @@ function mainStart(args) { if (config.letsencrypt != null) { modules.push('greenlock'); modules.push('le-store-certbot'); modules.push('le-challenge-fs'); modules.push('le-acme-core'); } // Add Greenlock Modules if (config.settings.mongodb != null) { modules.push('mongojs'); } // Add MongoDB if (config.smtp != null) { modules.push('nodemailer'); } // Add SMTP support + if (yubikey == true) { modules.push('yubikeyotp'); } // Add YubiKey OTP support // Get the current node version var nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]); @@ -1658,9 +1654,9 @@ function mainStart(args) { // If running NodeJS < 8, install "util.promisify" if (nodeVersion < 8) { modules.push('util.promisify'); } - // if running NodeJS 8 or higher, we can install WebAuthn/FIDO2 support - if ((nodeVersion >= 8) && (allsspi == false)) { modules.push('@davedoesdev/fido2-lib'); } - + // if not all SSPI, WebAuthn/FIDO2 or U2F support depending on the NodeJS version. FIDO2 does not work below NodeJS 8.x + if (allsspi == false) { modules.push('otplib'); if (nodeVersion >= 8) { modules.push('@davedoesdev/fido2-lib'); } else { modules.push('authdog'); } } + // Install any missing modules and launch the server InstallModules(modules, function () { meshserver = CreateMeshCentralServer(config, args); meshserver.Start(); }); }); @@ -1670,4 +1666,4 @@ if (require.main === module) { mainStart(require('minimist')(process.argv.slice(2))); // Called directly, launch normally. } else { module.exports.mainStart = mainStart; // Required as a module, useful for winservice.js -} \ No newline at end of file +} diff --git a/meshuser.js b/meshuser.js index 708297e6..fe0789cf 100644 --- a/meshuser.js +++ b/meshuser.js @@ -1773,7 +1773,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use const twoStepLoginSupported = ((domain.auth != 'sspi') && (parent.parent.certificates.CommonName.indexOf('.') != -1) && (args.lanonly !== true) && (args.nousers !== true)); if (twoStepLoginSupported) { // Request a one time password to be setup - const otplib = require('otplib'); + var otplib = null; + try { otplib = require('otplib'); } catch (ex) { } + if (otplib == null) { break; } const secret = otplib.authenticator.generateSecret(); // TODO: Check the random source of this value. ws.send(JSON.stringify({ action: 'otpauth-request', secret: secret, url: otplib.authenticator.keyuri(user.name, parent.certificates.CommonName, secret) })); } @@ -1785,7 +1787,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use const twoStepLoginSupported = ((domain.auth != 'sspi') && (parent.parent.certificates.CommonName.indexOf('.') != -1) && (args.lanonly !== true) && (args.nousers !== true)); if (twoStepLoginSupported) { // Perform the one time password setup - const otplib = require('otplib'); + var otplib = null; + try { otplib = require('otplib'); } catch (ex) { } + if (otplib == null) { break; } otplib.authenticator.options = { window: 2 }; // Set +/- 1 minute window if (otplib.authenticator.check(command.token, command.secret) === true) { // Token is valid, activate 2-step login on this account. @@ -1853,8 +1857,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use } case 'otp-hkey-get': { - - // Check is 2-step login is supported const twoStepLoginSupported = ((domain.auth != 'sspi') && (parent.parent.certificates.CommonName.indexOf('.') != -1) && (args.lanonly !== true) && (args.nousers !== true)); if (twoStepLoginSupported == false) break; @@ -1887,10 +1889,12 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use case 'otp-hkey-yubikey-add': { // Yubico API id and signature key can be requested from https://upgrade.yubico.com/getapikey/ + var yubikeyotp = null; + try { yubikeyotp = require('yubikeyotp'); } catch (ex) { } // Check is 2-step login is supported const twoStepLoginSupported = ((domain.auth != 'sspi') && (parent.parent.certificates.CommonName.indexOf('.') != -1) && (args.lanonly !== true) && (args.nousers !== true)); - if ((twoStepLoginSupported == false) || (typeof command.otp != 'string')) { + if ((yubikeyotp == null) || (twoStepLoginSupported == false) || (typeof command.otp != 'string')) { ws.send(JSON.stringify({ action: 'otp-hkey-yubikey-add', result: false, name: command.name })); break; } @@ -1904,7 +1908,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // TODO: Check if command.otp is modhex encoded, reject if not. // Query the YubiKey server to validate the OTP - var yubikeyotp = require('yubikeyotp'); var request = { otp: command.otp, id: domain.yubikey.id, key: domain.yubikey.secret, timestamp: true } if (domain.yubikey.proxy) { request.requestParams = { proxy: domain.yubikey.proxy }; } yubikeyotp.verifyOTP(request, function (err, results) { @@ -1934,16 +1937,19 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use } case 'otp-hkey-setup-request': { + var authdoglib = null; + try { authdoglib = require('authdog'); } catch (ex) { } + // Check is 2-step login is supported const twoStepLoginSupported = ((domain.auth != 'sspi') && (parent.parent.certificates.CommonName.indexOf('.') != -1) && (args.lanonly !== true) && (args.nousers !== true)); - if (twoStepLoginSupported == false) break; + if ((authdoglib == null) || (twoStepLoginSupported == false)) break; // Build list of known keys var knownKeys = []; if (user.otphkeys != null) { for (var i = 0; i < user.otphkeys.length; i++) { if (user.otphkeys[i].type == 1) { knownKeys.push(user.otphkeys[i]); } } } // Build a key registration request and send it over - require('authdog').startRegistration('https://' + parent.parent.certificates.CommonName, knownKeys, { requestId: 556, timeoutSeconds: 100 }).then(function (registrationRequest) { + authdoglib.startRegistration('https://' + parent.parent.certificates.CommonName, knownKeys, { requestId: 556, timeoutSeconds: 100 }).then(function (registrationRequest) { // Save registration request to session for later use obj.hardwareKeyRegistrationRequest = registrationRequest; @@ -1957,12 +1963,15 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use } case 'otp-hkey-setup-response': { + var authdoglib = null; + try { authdoglib = require('authdog'); } catch (ex) { } + // Check is 2-step login is supported const twoStepLoginSupported = ((domain.auth != 'sspi') && (parent.parent.certificates.CommonName.indexOf('.') != -1) && (args.lanonly !== true) && (args.nousers !== true)); - if ((twoStepLoginSupported == false) || (command.response == null) || (command.name == null) || (obj.hardwareKeyRegistrationRequest == null)) break; + if ((authdoglib == null) || (twoStepLoginSupported == false) || (command.response == null) || (command.name == null) || (obj.hardwareKeyRegistrationRequest == null)) break; // Check the key registration request - require('authdog').finishRegistration(obj.hardwareKeyRegistrationRequest, command.response).then(function (registrationStatus) { + authdoglib.finishRegistration(obj.hardwareKeyRegistrationRequest, command.response).then(function (registrationStatus) { var keyIndex = parent.crypto.randomBytes(4).readUInt32BE(0); ws.send(JSON.stringify({ action: 'otp-hkey-setup-response', result: true, name: command.name, index: keyIndex })); if (user.otphkeys == null) { user.otphkeys = []; } diff --git a/package - Copy.json b/package - Copy.json new file mode 100644 index 00000000..32321b16 --- /dev/null +++ b/package - Copy.json @@ -0,0 +1,57 @@ +{ + "name": "meshcentral", + "version": "0.3.0-x", + "keywords": [ + "Remote Management", + "Intel AMT", + "Active Management", + "Remote Desktop" + ], + "homepage": "http://meshcommander.com", + "description": "Web based remote computer management and file server", + "author": "Ylian Saint-Hilaire ", + "main": "meshcentral.js", + "bin": { + "meshcentral": "./bin/meshcentral" + }, + "license": "Apache-2.0", + "files": [ + "*.js", + "sample-config.json", + "license.txt", + "readme.txt", + "agents", + "public", + "views", + "bin" + ], + "dependencies": { + "archiver": "^3.0.0", + "authdog": "^0.1.1", + "body-parser": "^1.18.2", + "compression": "^1.7.3", + "connect-redis": "^3.4.0", + "cookie-session": "^2.0.0-beta.3", + "express": "^4.16.4", + "express-handlebars": "^3.0.0", + "express-ws": "^4.0.0", + "ipcheck": "^0.1.0", + "meshcentral": "*", + "minimist": "^1.2.0", + "mongojs": "^2.6.0", + "multiparty": "^4.2.1", + "nedb": "^1.8.0", + "node-forge": "^0.7.6", + "otplib": "^10.0.1", + "ws": "^6.1.2", + "xmldom": "^0.1.27", + "yauzl": "^2.10.0", + "yubikeyotp": "^0.2.0" + }, + "devDependencies": {}, + "repository": { + "type": "git", + "url": "https://github.com/Ylianst/MeshCentral.git" + }, + "readme": "readme.txt" +} diff --git a/package.json b/package.json index ea47357c..6f0afca5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.3.0-u", + "version": "0.3.0-y", "keywords": [ "Remote Management", "Intel AMT", @@ -27,7 +27,6 @@ ], "dependencies": { "archiver": "^3.0.0", - "authdog": "^0.1.1", "body-parser": "^1.18.2", "compression": "^1.7.3", "connect-redis": "^3.4.0", @@ -41,11 +40,9 @@ "multiparty": "^4.2.1", "nedb": "^1.8.0", "node-forge": "^0.7.6", - "otplib": "^10.0.1", "ws": "^6.1.2", "xmldom": "^0.1.27", - "yauzl": "^2.10.0", - "yubikeyotp": "^0.2.0" + "yauzl": "^2.10.0" }, "devDependencies": {}, "repository": { diff --git a/reinstall-modules.bat b/reinstall-modules.bat new file mode 100644 index 00000000..9cdccf75 --- /dev/null +++ b/reinstall-modules.bat @@ -0,0 +1 @@ +npm install archiver authdog body-parser compression connect-redis cookie-session express express-handlebars express-ws ipcheck minimist mongojs multiparty nedb node-forge otplib ws xmldom yauzl yubikeyotp \ No newline at end of file diff --git a/views/default-min.handlebars b/views/default-min.handlebars index ed3a51f1..e6465347 100644 --- a/views/default-min.handlebars +++ b/views/default-min.handlebars @@ -1 +1,13940 @@ - MeshCentral
{{{title}}}
{{{title2}}}

{{{logoutControl}}}

 

\ No newline at end of file + MeshCentral
{{{title}}}
{{{title2}}}

{{{logoutControl}}}

 

\ No newline at end of file diff --git a/views/login-min.handlebars b/views/login-min.handlebars index f2dee8d2..01f57ebd 100644 --- a/views/login-min.handlebars +++ b/views/login-min.handlebars @@ -1 +1,1287 @@ - MeshCentral - Login
{{{title}}}
{{{title2}}}

Welcome


\ No newline at end of file + MeshCentral - Login
{{{title}}}
{{{title2}}}

Welcome


\ No newline at end of file diff --git a/views/login-mobile-min.handlebars b/views/login-mobile-min.handlebars index 687c7d69..83023a87 100644 --- a/views/login-mobile-min.handlebars +++ b/views/login-mobile-min.handlebars @@ -1 +1,1217 @@ - MeshCentral - Login
{{{title}}}
{{{title2}}}
\ No newline at end of file + MeshCentral - Login
{{{title}}}
{{{title2}}}
\ No newline at end of file diff --git a/views/login-mobile.handlebars b/views/login-mobile.handlebars index 54815892..a1975a42 100644 --- a/views/login-mobile.handlebars +++ b/views/login-mobile.handlebars @@ -287,7 +287,34 @@ if ('{{loginmode}}' == '4') { try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null } - if ((hardwareKeyChallenge != null) && u2fSupported()) { + if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) { + hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), c => c.charCodeAt(0)).buffer; + + const publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout } + for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) { + publicKeyCredentialRequestOptions.allowCredentials.push( + { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), c => c.charCodeAt(0)), type: 'public-key', transports: ['usb', 'ble', 'nfc'], } + ); + } + + // New WebAuthn hardware keys + navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then( + function (rawAssertion) { + var assertion = { + id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))), + clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))), + userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))), + signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))), + authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))), + }; + Q('hwtokenInput').value = JSON.stringify(assertion); + QE('tokenOkButton', true); + Q('tokenOkButton').click(); + }, + function (error) { console.log('credentials-get error', error); } + ); + } else if ((hardwareKeyChallenge != null) && u2fSupported()) { + // Old U2F hardware keys window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) { if ((currentpanel == 4) && authResponse.signatureData) { Q('hwtokenInput').value = JSON.stringify(authResponse); @@ -300,7 +327,34 @@ if ('{{loginmode}}' == '5') { try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null } - if ((hardwareKeyChallenge != null) && u2fSupported()) { + if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) { + hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), c => c.charCodeAt(0)).buffer; + + const publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout } + for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) { + publicKeyCredentialRequestOptions.allowCredentials.push( + { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), c => c.charCodeAt(0)), type: 'public-key', transports: ['usb', 'ble', 'nfc'], } + ); + } + + // New WebAuthn hardware keys + navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then( + function (rawAssertion) { + var assertion = { + id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))), + clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))), + userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))), + signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))), + authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))), + }; + Q('resetHwtokenInput').value = JSON.stringify(assertion); + QE('resetTokenOkButton', true); + Q('resetTokenOkButton').click(); + }, + function (error) { console.log('credentials-get error', error); } + ); + } else if ((hardwareKeyChallenge != null) && u2fSupported()) { + // Old U2F hardware keys window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) { if ((currentpanel == 5) && authResponse.signatureData) { Q('resetHwtokenInput').value = JSON.stringify(authResponse); diff --git a/views/login.handlebars b/views/login.handlebars index f9a6b5c8..126de5d2 100644 --- a/views/login.handlebars +++ b/views/login.handlebars @@ -386,11 +386,11 @@ navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then( function (rawAssertion) { var assertion = { - id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))), //base64encode(rawAssertion.rawId), - clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))), //arrayBufferToString(rawAssertion.response.clientDataJSON), - userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))), //base64encode(rawAssertion.response.userHandle), - signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))), //base64encode(rawAssertion.response.signature), - authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))), //base64encode(rawAssertion.response.authenticatorData) + id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))), + clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))), + userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))), + signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))), + authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))), }; Q('hwtokenInput').value = JSON.stringify(assertion); QE('tokenOkButton', true); @@ -412,7 +412,34 @@ if ('{{loginmode}}' == '5') { try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null } - if ((hardwareKeyChallenge != null) && u2fSupported()) { + if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) { + hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), c => c.charCodeAt(0)).buffer; + + const publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout } + for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) { + publicKeyCredentialRequestOptions.allowCredentials.push( + { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), c => c.charCodeAt(0)), type: 'public-key', transports: ['usb', 'ble', 'nfc'], } + ); + } + + // New WebAuthn hardware keys + navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then( + function (rawAssertion) { + var assertion = { + id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))), + clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))), + userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))), + signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))), + authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))), + }; + Q('resetHwtokenInput').value = JSON.stringify(assertion); + QE('resetTokenOkButton', true); + Q('resetTokenOkButton').click(); + }, + function (error) { console.log('credentials-get error', error); } + ); + } else if ((hardwareKeyChallenge != null) && u2fSupported()) { + // Old U2F hardware keys window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) { if ((currentpanel == 5) && authResponse.signatureData) { Q('resetHwtokenInput').value = JSON.stringify(authResponse); diff --git a/webserver.js b/webserver.js index 4b32ff9a..b06c79f6 100644 --- a/webserver.js +++ b/webserver.js @@ -62,7 +62,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { const constants = (obj.crypto.constants ? obj.crypto.constants : require('constants')); // require('constants') is deprecated in Node 11.10, use require('crypto').constants instead. // Setup WebAuthn / FIDO2 - try { const { Fido2Lib } = require("@davedoesdev/fido2-lib"); obj.f2l = new Fido2Lib({ attestation: "none" }); } catch (ex) { console.log(ex); } + try { const { Fido2Lib } = require("@davedoesdev/fido2-lib"); obj.f2l = new Fido2Lib({ attestation: "none" }); } catch (ex) { } // Variables obj.parent = parent;