Skip to content

Commit

Permalink
release: 0.21.0 (#287)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshcanhelp authored Apr 22, 2021
1 parent f5ab42b commit e9a9382
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 2 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rules-templates",
"version": "0.20.1",
"version": "0.21.0",
"description": "Auth0 Rules Repository",
"main": "./rules",
"scripts": {
Expand Down
10 changes: 10 additions & 0 deletions rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,16 @@
],
"description": "<p>Please see the <a href=\"https://marketplace.auth0.com/integrations/vouched-id-verification\">Vouched integration</a> for more information and detailed installation instructions.</p>\n<p><strong>Required configuration</strong> (this Rule will be skipped if any of the below are not defined):</p>\n<ul>\n<li><code>VOUCHED_API_KEY</code> Your Private Key located in Vouched Dashboard</li>\n<li><code>VOUCHED_PUBLIC_KEY</code> Your Public Key located in Vouched Dashboard</li>\n</ul>\n<p><strong>Optional configuration:</strong></p>\n<ul>\n<li><code>VOUCHED_API_URL</code> Your Vouched API URL; leave blank unless instructed by your Vouched rep</li>\n<li><code>VOUCHED_ID_TOKEN_CLAIM</code> Set a <code>https://vouchedid/is_verified</code> claim in the ID token with results</li>\n<li><code>VOUCHED_VERIFICATION_OPTIONAL</code> Set to \"true\" to succeed even if verification fails</li>\n</ul>",
"code": "async function vouchedVerification(user, context, callback) {\n if (!configuration.VOUCHED_API_KEY || !configuration.VOUCHED_PUBLIC_KEY) {\n console.log('Missing required configuration. Skipping.');\n return callback(null, user, context);\n }\n\n /* ----------- START helpers ----------- */\n const axios = require('axios');\n const url = require('url');\n const { Auth0RedirectRuleUtilities } = require('@auth0/[email protected]');\n\n const ruleUtils = new Auth0RedirectRuleUtilities(\n user,\n context,\n configuration\n );\n\n const defaultApiUrl = 'https://verify.vouched.id/api';\n const defaultUiUrl = 'https://i.vouched.id';\n const idTokenClaim = 'https://vouched.id/is_verified';\n\n const getJobByToken = async (apiKey, jobToken, apiUrl) => {\n return getJob(apiKey, { token: jobToken }, apiUrl);\n };\n\n const getJobById = async (apiKey, jobId, apiUrl) => {\n return getJob(apiKey, { id: jobId }, apiUrl);\n };\n\n const getJob = async (apiKey, params, apiUrl) => {\n const response = await axios({\n headers: {\n 'X-Api-Key': apiKey,\n 'Content-Type': 'application/json'\n },\n baseURL: apiUrl,\n url: '/jobs',\n params: params\n });\n const items = response.data.items;\n if (items.length === 0) {\n throw new Error(\n `Unable to find Job with the following params: ${JSON.stringify(\n params\n )}`\n );\n }\n return items[0];\n };\n\n const createPacket = async (\n apiKey,\n publicKey,\n continueUrl,\n user,\n apiUrl = defaultApiUrl\n ) => {\n const requestBody = {\n pk: publicKey,\n uid: user.user_id,\n continueUrl\n };\n\n if (user.given_name) requestBody.firstName = user.given_name;\n\n if (user.family_name) requestBody.lastName = user.family_name;\n\n const response = await axios({\n method: 'post',\n headers: {\n 'X-Api-Key': apiKey,\n 'Content-Type': 'application/json'\n },\n baseURL: apiUrl,\n url: '/packet/auth0',\n data: requestBody\n });\n const data = response.data;\n if (data.errors) {\n throw new Error(`${data.errors[0].message}`);\n }\n return data.id;\n };\n\n const isJobForUser = (job, userId) => {\n try {\n return (\n job.request.properties.filter(\n (prop) => prop.name === 'uid' && prop.value === userId\n ).length === 1\n );\n } catch (e) {\n return false;\n }\n };\n\n const extractResults = (job) => {\n const { id, status, reviewSuccess, result } = job;\n return {\n id,\n status,\n reviewSuccess,\n result\n };\n };\n\n const isJobVerified = (job) => {\n try {\n return job.result.success || job.reviewSuccess;\n } catch (e) {\n return false;\n }\n };\n\n const redirectToVerification = (packetId, baseUrl = defaultUiUrl) => {\n const redirectUrl = new url.URL(`${baseUrl}/auth0`);\n redirectUrl.searchParams.append('id', packetId);\n return redirectUrl.href;\n };\n\n /* ----------- END helpers ----------- */\n\n user.app_metadata = user.app_metadata || {};\n const vouchedApiUrl = configuration.VOUCHED_API_URL || defaultApiUrl;\n\n try {\n const jobToken = ruleUtils.queryParams.jobToken;\n if (ruleUtils.isRedirectCallback && jobToken) {\n // get job from API\n const job = await getJobByToken(\n configuration.VOUCHED_API_KEY,\n jobToken,\n vouchedApiUrl\n );\n\n // check if job's user is the same as current user\n if (!isJobForUser(job, user.user_id)) {\n return callback(\n new Error(`The ID Verification results do not belong to this user.`)\n );\n }\n\n // update app metadata w/ results\n user.app_metadata.vouched = extractResults(job);\n await auth0.users.updateAppMetadata(user.user_id, user.app_metadata);\n }\n\n const vouchedResults = user.app_metadata.vouched;\n if (vouchedResults) {\n if (!isJobVerified(vouchedResults)) {\n // user failed id verification\n const mostRecentJob = await getJobById(\n configuration.VOUCHED_API_KEY,\n vouchedResults.id,\n vouchedApiUrl\n );\n\n // check if job's user is the same as current user\n if (!isJobForUser(mostRecentJob, user.user_id)) {\n return callback(\n new Error(`The ID Verification results do not belong to this user.`)\n );\n }\n\n // user is now verified, update app metadata\n if (isJobVerified(mostRecentJob)) {\n user.app_metadata.vouched = extractResults(mostRecentJob);\n await auth0.users.updateAppMetadata(user.user_id, user.app_metadata);\n } else {\n // user failed verification check and doesn't have an override\n if (configuration.VOUCHED_ID_TOKEN_CLAIM === 'true') {\n context.idToken[idTokenClaim] = false;\n }\n if (configuration.VOUCHED_VERIFICATION_OPTIONAL === 'true') {\n return callback(null, user, context);\n }\n\n return callback(new Error(`This user's ID cannot be verified.`));\n }\n }\n } else {\n // create Auth0 packet to securely pass info to Vouched\n const packetId = await createPacket(\n configuration.VOUCHED_API_KEY,\n configuration.VOUCHED_PUBLIC_KEY,\n `https://${context.request.hostname}/continue`,\n user\n );\n\n // user doesn't have a verification result, redirect to Vouched with packet\n if (ruleUtils.canRedirect) {\n context.redirect = { url: redirectToVerification(packetId) };\n }\n return callback(null, user, context);\n }\n } catch (e) {\n return callback(e);\n }\n\n if (configuration.VOUCHED_ID_TOKEN_CLAIM === 'true') {\n context.idToken[idTokenClaim] = true;\n }\n\n return callback(null, user, context);\n}"
},
{
"id": "yoonik-face",
"title": "YooniK Face Authentication",
"overview": "Redirect to your YooniK Face Application for Face Authentication during login.",
"categories": [
"marketplace"
],
"description": "<p><strong>Required configuration</strong> (this Rule will be skipped if any of the below are not defined):</p>\n<ul>\n<li><code>SESSION_TOKEN_SECRET</code> A random long string that is used to sign the session token sent\n to the custom app implementing YooniK Face Capture SDK. This value will also need to be\n used in the custom app in order to verify and re-sign the session token back to Auth0.</li>\n<li><code>YOONIK_APP_URL</code> The URL of your custom application that receives the redirect.</li>\n</ul>",
"code": "async function yoonikFaceAuthentication(user, context, callback) {\n if (!configuration.SESSION_TOKEN_SECRET || !configuration.YOONIK_APP_URL) {\n console.log('Please set required configuration parameters.');\n return callback(null, user, context);\n }\n\n const {\n Auth0RedirectRuleUtilities,\n Auth0UserUpdateUtilities\n } = require('@auth0/[email protected]');\n\n const ruleUtils = new Auth0RedirectRuleUtilities(\n user,\n context,\n configuration\n );\n\n const userUtils = new Auth0UserUpdateUtilities(user, auth0, 'yoonik');\n\n const claimNamespace = 'https://claims.yoonik.me/';\n\n if (\n ruleUtils.isRedirectCallback &&\n ruleUtils.queryParams.session_token &&\n ruleUtils.queryParams.yoonik_authentication === 'true'\n ) {\n // User is back from the YooniK redirect and has a session token to validate.\n let payload;\n try {\n payload = ruleUtils.validateSessionToken();\n } catch (error) {\n callback(error);\n }\n\n userUtils.setAppMeta('status', payload.status);\n\n try {\n await userUtils.updateAppMeta();\n } catch (error) {\n callback(error);\n }\n\n context.idToken[claimNamespace + 'status'] = payload.status;\n\n callback(null, user, context);\n }\n\n if (ruleUtils.canRedirect) {\n try {\n ruleUtils.doRedirect(configuration.YOONIK_APP_URL);\n callback(null, user, context);\n } catch (error) {\n callback(error);\n }\n }\n\n return callback(null, user, context);\n}"
}
]
},
Expand Down

0 comments on commit e9a9382

Please sign in to comment.