diff --git a/package-lock.json b/package-lock.json index f649e71f..5c67da18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "rules-templates", - "version": "0.16.1", + "version": "0.17.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 6d4052b5..f7b74ac6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rules-templates", - "version": "0.16.1", + "version": "0.17.0", "description": "Auth0 Rules Repository", "main": "./rules", "scripts": { diff --git a/rules.json b/rules.json index c7516d8a..9f30e7e3 100644 --- a/rules.json +++ b/rules.json @@ -626,16 +626,6 @@ { "name": "marketplace", "templates": [ - { - "id": "caisson-id-check", - "title": "Caisson ID Check", - "overview": "Validate US driver's licenses and international passports in real time.", - "categories": [ - "marketplace" - ], - "description": "

Please see the Caisson integration for more information and detailed installation instructions.

\n

Required configuration (this Rule will be skipped if any of the below are not defined):

\n\n

Optional configuration:

\n", - "code": "async function caissonIDCheck(user, context, callback) {\n if (\n !configuration.CAISSON_PUBLIC_KEY ||\n !configuration.CAISSON_PRIVATE_KEY ||\n !configuration.CAISSON_LOGIN_FREQUENCY_DAYS\n ) {\n console.log('Missing required configuration. Skipping.');\n return callback(null, user, context);\n }\n\n const { Auth0RedirectRuleUtilities } = require('@auth0/rule-utilities@0.1.0');\n\n //copy off the config obj so we can use our own private key for session token signing.\n let caissonConf = JSON.parse(JSON.stringify(configuration));\n caissonConf.SESSION_TOKEN_SECRET = configuration.CAISSON_PRIVATE_KEY;\n\n const manager = {\n creds: {\n public_key: caissonConf.CAISSON_PUBLIC_KEY,\n private_key: caissonConf.CAISSON_PRIVATE_KEY\n },\n /* prettier-ignore */\n debug: caissonConf.CAISSON_DEBUG && caissonConf.CAISSON_DEBUG.toLowerCase() === \"true\" ? true : false,\n idCheckFlags: {\n login_frequency_days: parseInt(\n caissonConf.CAISSON_LOGIN_FREQUENCY_DAYS,\n 10\n )\n },\n caissonHosts: {\n idcheck: 'https://id.caisson.com',\n api: 'https://api.caisson.com',\n dashboard: 'https://www.caisson.com'\n },\n axios: require('axios@0.19.2'),\n util: new Auth0RedirectRuleUtilities(user, context, caissonConf)\n };\n\n user.app_metadata = user.app_metadata || {};\n user.app_metadata.caisson = user.app_metadata.caisson || {};\n const caisson = user.app_metadata.caisson;\n\n /**\n * Toggleable logger. Set CAISSON_DEBUG in the Auth0 configuration to enable.\n *\n * @param {error} err\n */\n function dLog(err) {\n if (manager.debug) {\n console.log(err);\n }\n }\n\n /**\n * Helper function for converting milliseconds to days. Results rounded down.\n * @param {int} mils\n */\n function millisToDays(mils) {\n return Math.floor(mils / 1000 / 60 / 60 / 24);\n }\n\n /**\n * Creates Caisson specific session token and sets redirect url.\n */\n function setIDCheckRedirect() {\n const token = manager.util.createSessionToken({\n public_key: manager.creds.public_key,\n host: context.request.hostname\n });\n\n //throws if redirects aren't allowed here.\n manager.util.doRedirect(`${manager.caissonHosts.idcheck}/auth0`, token); //throws\n }\n\n /**\n * Swaps the temp Caisson exchange token for an ID Check key.\n * https://www.caisson.com/docs/reference/api/#exchange-check-token-for-check-id\n * @param {string} t\n */\n async function exchangeToken() {\n try {\n let resp = await manager.axios.post(\n manager.caissonHosts.api + '/v1/idcheck/exchangetoken',\n { check_exchange_token: manager.util.queryParams.t },\n {\n headers: {\n Authorization: `Caisson ${manager.creds.private_key}`\n }\n }\n );\n\n return resp.data.check_id;\n } catch (error) {\n let err = error;\n if (err.response && err.response.status === 401) {\n err = new UnauthorizedError(\n 'Invalid private key. See your API credentials at https://www.caisson.com/developer .'\n );\n }\n throw err;\n }\n }\n\n /**\n * Fetches and validates ID Check results.\n * https://www.caisson.com/docs/reference/api/#get-an-id-check-result\n * @param {string} check_id\n */\n async function idCheckResults(check_id) {\n try {\n let resp = await manager.axios.get(\n manager.caissonHosts.api + '/v1/idcheck',\n {\n headers: {\n Authorization: `Caisson ${manager.creds.private_key}`,\n 'X-Caisson-CheckID': check_id\n }\n }\n );\n\n if (resp.data.error) {\n throw new Error(\n 'Error in Caisson ID Check: ' + JSON.stringify(resp.data)\n );\n }\n\n let results = {\n check_id: resp.data.check_id,\n auth0_id: resp.data.customer_id,\n timestamp: resp.data.checked_on,\n /* prettier-ignore */\n status: resp.data.confidence.document === \"high\" && resp.data.confidence.face === \"high\" ? \"passed\" : \"flagged\"\n };\n\n validateIDCheck(results); //throws if invalid\n\n return results;\n } catch (error) {\n let err = error;\n if (err.response && err.response.status === 401) {\n err = new UnauthorizedError(\n 'Invalid private key. See your API credentials at https://www.caisson.com/developer .'\n );\n }\n\n throw err;\n }\n }\n\n /**\n * Validates Caisson ID Check results, ensuring the data is usable.\n * @param {object} results\n */\n function validateIDCheck(results) {\n const IDCheckTTL = 20 * 60 * 1000; //20 mins\n if (\n results.auth0_id !==\n user.user_id + '__' + manager.util.queryParams.state\n ) {\n throw new UnauthorizedError(\n 'ID mismatch. Caisson: %o, Auth0: %o',\n results.auth0_id,\n user.user_id\n );\n } else if (Date.now() - Date.parse(results.timestamp) > IDCheckTTL) {\n throw new UnauthorizedError('ID Check too old.');\n }\n }\n\n /**\n * Updates Caisson values on the Auth0 user object's app_metadata object.\n * @param {object} results\n */\n async function updateUser(results) {\n caisson.idcheck_url =\n manager.caissonHosts.dashboard + '/request/' + results.check_id;\n caisson.status = results.status;\n caisson.last_check = Date.now();\n caisson.count = caisson.count ? caisson.count + 1 : 1;\n\n try {\n await auth0.users.updateAppMetadata(user.user_id, { caisson });\n } catch (err) {\n throw err;\n }\n }\n\n /**\n * ID Check is done, handle results.\n */\n if (manager.util.isRedirectCallback) {\n //is it our redirect?\n\n if (\n !manager.util.queryParams.caisson_flow ||\n parseInt(manager.util.queryParams.caisson_flow, 10) !== 1\n ) {\n //no, end it.\n return callback(null, user, context);\n }\n\n try {\n if (!manager.util.queryParams.t) {\n throw new Error('Missing Caisson exchange key');\n }\n\n const check_id = await exchangeToken();\n const results = await idCheckResults(check_id);\n await updateUser(results);\n\n //deny the login if the ID Check is flagged\n if (results.status === 'flagged') {\n throw new UnauthorizedError('ID Check flagged.');\n }\n } catch (err) {\n dLog(err);\n return callback(err);\n }\n\n return callback(null, user, context);\n }\n\n /**\n * Else we're in the initial auth flow.\n * Perform ID Checks when appropriate.\n */\n\n try {\n if (isNaN(manager.idCheckFlags.login_frequency_days)) {\n //Do nothing. Skip if no preference is set.\n } else if (!caisson.last_check || caisson.status !== 'passed') {\n //Always perform the first ID Check or if the\n //last ID Check didn't pass.\n setIDCheckRedirect();\n } else if (\n manager.idCheckFlags.login_frequency_days >= 0 &&\n millisToDays(Date.now() - caisson.last_check) >=\n manager.idCheckFlags.login_frequency_days\n ) {\n //ID Check if the requisite number of days have passed since the last check.\n //Skip if we're only supposed to check once (login_frequency_days < -1).\n setIDCheckRedirect();\n }\n } catch (err) {\n dLog(err);\n return callback(err);\n }\n\n return callback(null, user, context);\n}" - }, { "id": "eva-voice-biometric", "title": "EVA Voice Biometric connector",