{"info":{"_postman_id":"ea50e15b-7acc-4bdf-9221-1d47fc8c0550","name":"Smart Hooks - OneLogin API","description":"<html><head></head><body><p>Smart Hooks let developers and IT teams extend OneLogin in ways never possible before. From creating conditional access login flows to augmenting user lifecycle events we can’t wait to see what you build.</p>\n<h2 id=\"pre-request-scripts\">Pre Request Scripts</h2>\n<p>We have taken advantage of the Pre Request Scripts tab in Postman for enabling easy editing of javascript functions. </p>\n<p>The pre request script will Base64 encode the function before sending it to the Smart Hooks API.</p>\n</body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[],"owner":"2629710","collectionId":"ea50e15b-7acc-4bdf-9221-1d47fc8c0550","publishedId":"TVemA9DP","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"00A9E0"},"publishDate":"2020-11-11T00:41:21.000Z"},"item":[{"name":"Pre-Authentication Hook","item":[{"name":"Create minimum viable function","event":[{"listen":"prerequest","script":{"id":"f8b272f8-a671-4fb3-8cd3-3ed12e24dd12","exec":["","const functionString = `","exports.handler = async (context) => {","    console.log(context);","    return {","        success: true,","        user: context.user","    }","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript"}}],"id":"cd8a4d26-f60e-429a-8cb5-07eacb0e889e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[{"key":"Content-Type","type":"text","value":"application/json"}],"body":{"mode":"raw","raw":"{\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n    \"context_version\": \"1.1.0\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks","description":"<p>This function simply passes the user immediately back without making any changes to user policy. It is effectively a waste of time having a hook like this but it serves the purpose of showing what a minimum viable pre-authentication hook would look like.</p>\n","urlObject":{"protocol":"https","path":["api","2","hooks"],"host":["{{api-domain}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"cd8a4d26-f60e-429a-8cb5-07eacb0e889e"},{"name":"Update minimum viable function","event":[{"listen":"prerequest","script":{"id":"cd5e26eb-0cf9-4abb-bb4a-fd507b08e5b6","exec":["","const functionString = `","exports.handler = async (context) => {","    console.log(context);","    return {","        success: true,","        user: context.user","    }","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"1390ba19-9355-4ea4-b38c-e719b6a52a52","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1, \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","description":"<p>This function simply passes the user immediately back without making any changes to user policy. It is effectively a waste of time having a hook like this but it serves the purpose of showing what a minimum viable pre-authentication hook would look like.</p>\n","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"1390ba19-9355-4ea4-b38c-e719b6a52a52"},{"name":"Deny Access based on Country Code","event":[{"listen":"prerequest","script":{"id":"f8b272f8-a671-4fb3-8cd3-3ed12e24dd12","exec":["","const functionString = `","exports.handler = async (context) => {","    console.log(\"Context \", context);","","    // Deny access","    if (context.location.country_code != \"NZ\") return { success: false, user: null };","    ","    return {","        success: true,","        user: context.user","    };","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"40751463-432e-462f-919c-321b63004e37","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": true,\n    \t\"location_enabled\": true,\n        \"mfa_device_info_enabled\": false\n    },  \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"40751463-432e-462f-919c-321b63004e37"},{"name":"Only Allow users from specific countries to login","event":[{"listen":"prerequest","script":{"id":"f8b272f8-a671-4fb3-8cd3-3ed12e24dd12","exec":["","const functionString = `","exports.handler = async context => {","  // A list of ISO 3166 Alpha 2 character country codes","  // https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2","  const ALLOWED_COUNTRY_CODES = [\"US\", \"NZ\"]","","  let allowAccess = ALLOWED_COUNTRY_CODES.includes(context.location.country_code);","","  return {","    success: allowAccess,","    user: context.user","  };","};","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"4176d1d7-ac14-470b-bb9e-4844bc98b2b0","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": false,\n    \t\"location_enabled\": true,\n        \"mfa_device_info_enabled\": false\n    },  \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","description":"<p>This Smart Hook will block all users from logging in unless they come from one of the listed countries. </p>\n","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"4176d1d7-ac14-470b-bb9e-4844bc98b2b0"},{"name":"Require MFA based on Country Code","event":[{"listen":"prerequest","script":{"id":"d3e961f0-3c41-4867-a7d3-1612c1718b5f","exec":["","const functionString = `","exports.handler = async (context) => {","    console.log(\"Context \", context);","    ","    var user = context.user;","    const policy_id = (context.location.country_code == \"NZ\") ? 135379 : user.policy_id","","    return {","        success: true,","        user: { ...user, policy_id }","    }","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"928f80c5-20be-4536-aea1-afa55f8bec70","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": false,\n    \t\"location_enabled\": true,\n        \"mfa_device_info_enabled\": false\n    },  \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"928f80c5-20be-4536-aea1-afa55f8bec70"},{"name":"Deny Access to IE 11","event":[{"listen":"prerequest","script":{"id":"f8b272f8-a671-4fb3-8cd3-3ed12e24dd12","exec":["","const functionString = `","const parser = require('ua-parser-js');","","const isIe11 = ({ name, version }) => name == \"IE\" && version == \"11.0\";","","const ie11PolicyOverride = ({ user, device }) => {","    const { browser } = parser(device.user_agent);","    ","    if (isIe11(browser)) return { success: false, user: null };","","    return {","        success: true,","        user: user","    }","} ","","exports.handler = async (context) => {","    return ie11PolicyOverride(context);","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"131eaced-4a1b-4bd9-87d5-971085cdfdad","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": true,\n    \t\"location_enabled\": true,\n        \"mfa_device_info_enabled\": false\n    },  \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n\t\t\"ua-parser-js\": \"0.7.21\"\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","description":"<p>This hook uses an NPM package to parse the user agent string and deny access based on the type of browser that has been used.</p>\n","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"131eaced-4a1b-4bd9-87d5-971085cdfdad"},{"name":"Change User Policy based on Browser type","event":[{"listen":"prerequest","script":{"id":"63c2ead5-4ec3-4158-a9b3-b263b40a0eb8","exec":["","const functionString = `","const parser = require('ua-parser-js');","","exports.handler = async (context) => {","    const { browser } = parser(context.device.user_agent);","    ","    let user = context.user;","","    // If the user has one of these browsers then change the User Policy","    // If they have a different browser then they will continue with their assigned User Policy","    switch (browser.name) {","        // case \"Edge\": ","        //     user.policy_id = 123456;","        //     break;","        // case \"Chrome\":","        //     user.policy_id = 123133;","        //     break;        ","        // case \"Firefox\":","        //     user.policy_id = 123123;","        //     break;        ","        // case \"Safari\":","        //     user.policy_id = 627214;","        //     break;        ","    }","","    console.log(\"User\", user);","","    return {","        success: true,","        user: user","    }","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"b5c7de00-be22-4e43-9641-3b78fea4fc50","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": false,\n    \t\"location_enabled\": false,\n        \"mfa_device_info_enabled\": false\n    },  \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n\t\t\"ua-parser-js\": \"0.7.21\"\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","description":"<p>This hook uses an NPM package to parse the user agent string and deny access based on the type of browser that has been used.</p>\n<ul>\n<li>If the user has one of the defined browsers then change the User Policy. </li>\n<li>If they have a browser that is not included in the list then they will continue with their assigned User Policy</li>\n</ul>\n","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"b5c7de00-be22-4e43-9641-3b78fea4fc50"},{"name":"Change User Policy for Mobile Devices","event":[{"listen":"prerequest","script":{"id":"f8b272f8-a671-4fb3-8cd3-3ed12e24dd12","exec":["","const functionString = `","exports.handler = async (context) => {","    console.log(context);","","    const MOBILE_POLICY_ID = 90002;","","    let user = context.user;","    console.log(\"Users Assigned Policy ID is \" + user.policy_id);","","    if (context.device.is_mobile) {","        user.policy_id = MOBILE_POLICY_ID;","        console.log(\"Mobile device detected. Changing policy id to \" + user.policy_id);        ","    } ","","    return {","        success: true,","        user: user","    }","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"9a577e41-81d1-407d-9611-74f40a0e2db3","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": false,\n    \t\"location_enabled\": false,\n        \"mfa_device_info_enabled\": false\n    },  \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"9a577e41-81d1-407d-9611-74f40a0e2db3"},{"name":"Post to Slack on High Risk","event":[{"listen":"prerequest","script":{"id":"cd5e26eb-0cf9-4abb-bb4a-fd507b08e5b6","exec":["","const functionString = `","","const axios = require(\"axios\")","const RISK_THRESHOLD = 50;","","exports.handler = async context => {","  try {","      if (context.risk.score > RISK_THRESHOLD) {","          const payload = JSON.stringify({","              channel: \"#integrations\", ","              username: \"onelogin_hooks_bot\", ","              text: \"Eeek! High risk login (score: \" + context.risk.score + \")  detected for \" + context.user.user_identifier,     ","              icon_emoji: \":scream:\"","          });","","          const options = {","              headers: {","                  \"Content-Type\": \"application/x-www-form-urlencoded\" ","              }","          }","","          const response = await axios.post(process.env.SLACK_WEBHOOK_URL, payload, options);","          console.log(\"Response Status: \" + response.statusText);","          console.log(response.data);","      }","  }","  catch (error) {","      console.log(error.toJSON());","  }","","  return {","      success: true,","      user: context.user","  }","};","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"ceeca030-1b4e-46e3-b526-6eae619e4073","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n    \"context_version\": \"1.1.0\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": true\n    },  \n\t\"env_vars\": [\n        \"SLACK_WEBHOOK_URL\"\n\t],\n\t\"packages\": {\n        \"axios\": \"0.21.1\"        \n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"ceeca030-1b4e-46e3-b526-6eae619e4073"},{"name":"Switch to Cisco AnyConnect policy based on User Agent","event":[{"listen":"prerequest","script":{"id":"cd5e26eb-0cf9-4abb-bb4a-fd507b08e5b6","exec":["const functionString = `","    const parser = require(\"ua-parser-js\");","","    const ANYCONNECT_POLICY_ID = 1234;","","    const anyconnectBrowser = [","        [/(AnyConnect)\\\\/(\\\\d+)(?:\\\\.(\\\\d+)|)(?:\\\\.(\\\\d+)|)/i],","        [parser.BROWSER.NAME, parser.BROWSER.VERSION]","    ];","","    const uaExtensions = { browser: anyconnectBrowser };","","    exports.handler = async context => {","        const ua = parser(context.device.user_agent, uaExtensions);","","        // Overrides the policy ID if the browser type is AnyConnect,","        // otherwise, use the default policy_id already assigned to the user","        const policy_id = ua.browser.name === 'AnyConnect'","            ? ANYCONNECT_POLICY_ID","            : context.user.policy_id;","","        return {","            success: true,","            user: { policy_id }","        };","    };","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"dab0e6a8-55ed-4ffb-b9a2-d9e11b134dd1","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": false,\n    \t\"location_enabled\": true,\n        \"mfa_device_info_enabled\": false\n    },  \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n        \"ua-parser-js\": \"0.7.23\"        \n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","description":"<p>This pre-authentication hook will look for a specific useragent string that is used by the Cisco Anypoint Connect VPN client and then force the user to switch to the defined user policy. </p>\n<p>Simply change the ANYCONNECT_POLICY_ID value to the ID of the user policy that you want to use. </p>\n","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"dab0e6a8-55ed-4ffb-b9a2-d9e11b134dd1"},{"name":"Change User Policy by IP Range","event":[{"listen":"prerequest","script":{"id":"cd5e26eb-0cf9-4abb-bb4a-fd507b08e5b6","exec":["const functionString = `","    const ipRangeCheck = require(\"ip-range-check\");","","    // List of IPv4 or IPv6 CIDR ranges","    const IP_RANGES = [\"2001:0db8:85a3:0000:0000:8a2e:0370:7334\", \"2001:4860:4860::8888/32\", \"1.1.1.1\", \"192.168.1.2/24\"]","","    // The policy id to assign if the users ip falls into the IP_RANGES","    const TARGET_POLICY_ID = 8888;","","    exports.handler = async context => {","","    // Defaults to the policy id currently assigned to the user","    let policy_id_to_assign = context.user.policy_id;","","    try {","        if (ipRangeCheck(context.location.ip, IP_RANGES)){","            policy_id_to_assign = TARGET_POLICY_ID;","        }","    }","    catch (e) {","        console.log(\"Error checking ip range \", e);","    }","","    return {","        success: true,","        user: { ","            policy_id: policy_id_to_assign ","        }","    };","    };","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"94aa6166-839c-415e-aea1-ae05e46050e8","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": false,\n    \t\"location_enabled\": true,\n        \"mfa_device_info_enabled\": false\n    },  \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n        \"ip-range-check\": \"0.2.0\"     \n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","description":"<p>Use this pre-authentication hook to change a user policy based on the users IP address being included in an IPv4 or IPv6 CIDR range. </p>\n","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"94aa6166-839c-415e-aea1-ae05e46050e8"},{"name":"Require MFA every X number of days","event":[{"listen":"prerequest","script":{"id":"cd5e26eb-0cf9-4abb-bb4a-fd507b08e5b6","exec":["const functionString = `","const moment = require(\"moment\");","","// The policy ID to use for requiring an MFA device.","const MFA_POLICY_ID = 54321;","","// The maximum number of days that may be allowed before MFA needs to be reprompted","const DAYS_THRESHOLD = 30;","","const response = (policy_id) => {","  return {","    success: true,","    user: { policy_id }","  };","};","","exports.handler = async (context) => {","  if (context.mfa_devices.length === 0) {","    return response(context.user.policy_id);","  }  ","","  let mfaDevicesByUsageOrder = context.mfa_devices.sort(function(a,b){","    return new Date(b.last_used_at) - new Date(a.last_used_at);","  });  ","","  let days = moment.utc().diff(mfaDevicesByUsageOrder[0].last_used_at, 'days');","","  // Evaluate the number of days against the threshold","  if (days > DAYS_THRESHOLD) {","    return response(MFA_POLICY_ID);","  } else {","    return response(context.user.policy_id);","  }","};","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"e49ce046-2c00-436c-9143-417c88bdad95","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"context_version\": \"1.1.0\",\n    \"options\":{\n\t    \"risk_enabled\": false,\n    \t\"location_enabled\": false,\n        \"mfa_device_info_enabled\": true\n    },  \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n        \"moment\": \"2.29.1\"\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","description":"<p>Use this hook to require users to perform MFA every X number of days.</p>\n","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"e49ce046-2c00-436c-9143-417c88bdad95"},{"name":"Reset Password after X without logging in","event":[{"listen":"prerequest","script":{"id":"cd5e26eb-0cf9-4abb-bb4a-fd507b08e5b6","exec":["const functionString = `","    // The policy id to assign if the users has not logged in for X days","    const TARGET_POLICY_ID = 88888;","","    // User will be forced to change password after this many days","    const NUMBER_OF_DAYS_SINCE_LAST_LOGIN = 30","","    exports.handler = async context => {","        let policy_id_to_assign = context.user.policy_id; // Defaults to users assigned policy ","","        if(context.user.last_login_success){","            let today = new Date();","            let change_policy_date = new Date().setDate(today.getDate() - NUMBER_OF_DAYS_SINCE_LAST_LOGIN);","            let last_login_date = new Date(context.user.last_login_success);","        ","            if(last_login_date < change_policy_date) {","                policy_id_to_assign = TARGET_POLICY_ID;","            }","        }","","        return {","            success: true,","            user: { ","                policy_id: policy_id_to_assign ","            }","        };","    };","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"76eb25ff-9c8b-4f9c-a034-5633c04a57ac","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"type\": \"pre-authentication\",\n    \"context_version\": \"1.1.0\",\n    \"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n    \"retries\": 0,\n    \"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": false,\n    \t\"location_enabled\": false,\n        \"mfa_device_info_enabled\": false\n    },  \n    \"function\": \"{{base64Function}}\",\n    \"env_vars\": [],\n    \"packages\": {\n    }\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","description":"<p>This hook example requires that a User Policy has been configured with a Maximum Password Age of 1 day. This will be consider as the Password Reset policy. </p>\n<p>If they user has not logged in for X number of days then the user will be switched to the Password Reset policy and prompted to change their password.</p>\n","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"76eb25ff-9c8b-4f9c-a034-5633c04a57ac"},{"name":"Change User Policy based on High Risk","event":[{"listen":"prerequest","script":{"id":"f8b272f8-a671-4fb3-8cd3-3ed12e24dd12","exec":["","const functionString = `","exports.handler = async (context) => {","    console.log(context);","","    const POLICY_ID = 90002;","    const RISK_THRESHOLD = 90;","","    let user = context.user;","    console.log(\"Users Assigned Policy ID is \" + user.policy_id);","","    if (context.risk.score > RISK_THRESHOLD) {","        user.policy_id = POLICY_ID;","        console.log(\"High risk detected. Changing policy id to \" + user.policy_id);        ","    } ","","    return {","        success: true,","        user: user","    }","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"075754ae-c537-48d4-bc1a-5a7d68ca00db","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": true,\n    \t\"location_enabled\": false,\n        \"mfa_device_info_enabled\": false\n    },  \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"075754ae-c537-48d4-bc1a-5a7d68ca00db"},{"name":"Change User Policy based on MFA Enrollment","event":[{"listen":"prerequest","script":{"id":"cd5e26eb-0cf9-4abb-bb4a-fd507b08e5b6","exec":["const functionString = `","// If the user has this MFA factor registered then we will change to a policy ","// that forces them to use it. ","const MFA_DEVICE_USER_DISPLAY_NAME = 'OneLogin SMS';","","// The policy ID that forces them to use the factor named above.","const MFA_POLICY_ID = 54321;","","const response = function (success, policy_id){","  return {","    success: success,","    user: { ","      policy_id ","    }","  }","};","","exports.handler = async context => {","  try {","    if (context.mfa_devices.length === 0) {","      return response(true, context.user.policy_id);","    }","  ","    const device = context.mfa_devices.find( ({ user_display_name }) => user_display_name === MFA_DEVICE_USER_DISPLAY_NAME );","","    if(device){","      return response(true, MFA_POLICY_ID);","    }","  ","    return response(true, context.user.policy_id);","","  } catch (error) {","    console.log(error);","    return response(false, context.user.policy_id);","  }","};   ","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"be968192-28dd-4117-bb2d-9376030c6e74","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"context_version\": \"1.1.0\",\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": false,\n    \t\"location_enabled\": false,\n        \"mfa_device_info_enabled\": true\n    },  \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","description":"<p>Use this hook example to change the user policy based on a specific MFA device being registered. </p>\n","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"be968192-28dd-4117-bb2d-9376030c6e74"},{"name":"Change Policy for New Users","event":[{"listen":"prerequest","script":{"id":"cd5e26eb-0cf9-4abb-bb4a-fd507b08e5b6","exec":["","const functionString = `","","const NEW_USER_POLICY_ID = 12345;","","exports.handler = async (context) => {","    console.log(context);","","    let policy_id = context.user.policy_id;","","    if (!context.user.last_login_success) {","        policy_id = NEW_USER_POLICY_ID","    }","","    return {","        success: true,","        user: {","            policy_id: policy_id","        }  ","    };","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"3e68a1f3-9fb8-49e3-914f-cb50710186e2","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n    \"context_version\": \"1.1.0\",\n\t\"retries\": 0,\n\t\"timeout\": 1, \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"any","value":"","key":"hook_id"}]}},"response":[],"_postman_id":"3e68a1f3-9fb8-49e3-914f-cb50710186e2"},{"name":"Switch policy to allow MFA Enrollment","event":[{"listen":"prerequest","script":{"id":"cd5e26eb-0cf9-4abb-bb4a-fd507b08e5b6","exec":["const functionString = `","// If they dont have any MFA devices registered then switch them to this policy","const MFA_POLICY_ID = 54321;","","const response = function (success, policy_id){","  return {","    success: success,","    user: { ","      policy_id ","    }","  }","};","","exports.handler = async context => {","  try {","    if (context.mfa_devices.length === 0) {","      return response(true, MFA_POLICY_ID);","    }","  ","    return response(true, context.user.policy_id);","","  } catch (error) {","    console.log(error);","    return response(false, context.user.policy_id);","  }","};   ","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"dbbb0460-5767-415c-9bfe-202d92b96471","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"context_version\": \"1.1.0\",\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": false,\n    \t\"location_enabled\": false,\n        \"mfa_device_info_enabled\": true\n    },  \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"dbbb0460-5767-415c-9bfe-202d92b96471"}],"id":"90836b6b-8337-462b-89db-2157ec15e80c","description":"<p>The <code>pre-authentication</code> hook runs synchronously as part of a UI based login flow. The hook fires immediately after the user enters a username/email but before they enter their password or are prompted for multi-factor authentication.</p>\n","event":[{"listen":"prerequest","script":{"id":"a5d39b3a-f56c-439d-8c7b-08e55d007c7b","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"9310d701-c47d-42ad-8fa6-c70a47b81bae","type":"text/javascript","exec":[""]}}],"_postman_id":"90836b6b-8337-462b-89db-2157ec15e80c","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":true,"source":{"_postman_id":"ea50e15b-7acc-4bdf-9221-1d47fc8c0550","id":"ea50e15b-7acc-4bdf-9221-1d47fc8c0550","name":"Smart Hooks - OneLogin API","type":"collection"}}},{"name":"User-Migration Hook","item":[{"name":"Migrate user via external API","event":[{"listen":"prerequest","script":{"id":"ce1a4f0a-9af0-495b-aaa5-107a96f883df","exec":["const functionString = `","const axios = require(\"axios\");","","const AUTHENTICATION_API_ENDPOINT = \"https://example.com/auth\";","const AUTHENTICATION_API_BEARER_TOKEN = \"your-access-token-here\";","","exports.handler = async (context) => {","    // Its not considered good practice to log the user context on ","    // this hook as it contains a password. Only enable this for debugging","    // console.log(context);","","    let user;","","    try {","        const response = await axios.post(AUTHENTICATION_API_ENDPOINT, {","            username: context.user_identifier,","            password: context.password","        }, {","            headers: { ","                \"Authorization\": \"Bearer \" + AUTHENTICATION_API_BEARER_TOKEN","            }","        });","        console.log(response.data);","","        if (response.data) {","            // Success - Create the user","            return {","                success: true,","                user: {","                    username: context.user_identifier,","                    password: context.password,","                    firstname: response.data.firstname,","                    lastname: response.data.lastname,","                    email: response.data.email","                }","            };            ","        } ","    }","    catch (error) {","        console.log(\"Error authenticating user \", error);         ","    }  ","","    // Fail closed. Dont create the user. Deny access","    return {","        success: false,","        user: {}","    }     ","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);","",""],"type":"text/javascript","packages":{}}}],"id":"c5c46c2a-767f-4d33-902e-9ee46af3b058","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n\t\"type\": \"user-migration\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"context_version\": \"1.0.0\",\n\t\"retries\": 0,\n    \"runtime\": \"nodejs18.x\",\n\t\"timeout\": 10,\n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n        \"axios\": \"0.21.1\"\n\t}   \n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks","description":"<p>This User-Migration Smart Hook example shows how you can connect to an external API to verify a usernames/password and extract information about the user. </p>\n<p>This example can be easily adjusted to work with most user validation APIs.</p>\n","urlObject":{"protocol":"https","path":["api","2","hooks"],"host":["{{api-domain}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"c5c46c2a-767f-4d33-902e-9ee46af3b058"},{"name":"Migrate user from Auth0","event":[{"listen":"prerequest","script":{"id":"9249e44c-5a77-4972-84a2-39ce1f1b7192","exec":["const functionString = `","const axios = require(\"axios\");","const jwt = require('jsonwebtoken');","const jwksClient = require('jwks-rsa');","","function getKey(header, callback){","  var client = jwksClient({","    jwksUri: \"https://\" + process.env.AUTH0_SUBDOMAIN + \".auth0.com/.well-known/jwks.json\"","  });","","  client.getSigningKey(header.kid, function(err, key) {","    var signingKey = key.publicKey || key.rsaPublicKey;","    callback(null, signingKey);","  });","}","","async function verifyJWT(token) {","  return new Promise(","    (resolve, reject) => {","      jwt.verify(token, getKey, {}, function(err, decoded) {","        resolve(decoded)","      });      ","    }","  );","}","","exports.handler = async (context) => {","    // Its not considered good practice to log the user context on ","    // this hook as it contains a password. Only enable this for debugging","    // console.log(context);","","    let user;","","    try {","      // Do a password grant request to validate the password","      const response = await axios.post(\"https://\" + process.env.AUTH0_SUBDOMAIN + \".auth0.com/oauth/token\", {","          grant_type: \"password\",","          username: context.user_identifier,","          password: context.password,","          scope: \"openid\",","          client_id: process.env.AUTH0_CLIENT_ID,","          client_secret: process.env.AUTH0_CLIENT_SECRET","      }, {","          headers: { ","              \"Content-Type\": \"application/json\"","          }","      });","      // console.log(response);","","      if (response.data) {","        let decodedToken = await verifyJWT(response.data.id_token);","        console.log(decodedToken);","","        let name = decodedToken.name.split(\" \");","","        return {","          success: true,","          user: {","            username: context.user_identifier,","            password: context.password,","            firstname: name.shift(),","            lastname: name.join(\" \"),","            email: decodedToken.email","          }","        };          ","      }","    }","    catch (error) {","        console.log(\"Error authenticating user \", error);         ","    }  ","    ","    // Fail closed. Dont create the user. Deny access","    return {","        success: false,","        user: {}","    }       ","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);","",""],"type":"text/javascript","packages":{}}}],"id":"7e5bad1d-a1a6-4100-bc1b-131740c24628","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n\t\"type\": \"user-migration\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"context_version\": \"1.0.0\",\n\t\"retries\": 0,\n    \"runtime\": \"nodejs18.x\",\n\t\"timeout\": 10,\n\t\"env_vars\": [\n        \"AUTH0_SUBDOMAIN\",\n        \"AUTH0_CLIENT_ID\",\n        \"AUTH0_CLIENT_SECRET\"\n\t],\n\t\"packages\": {\n        \"axios\": \"0.21.1\",\n        \"jwks-rsa\": \"2.0.1\",\n        \"jsonwebtoken\": \"8.5.1\"\n\t}   \n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks","description":"<p>This user-migration hook lets you import users into OneLogin from an Auth0 account. </p>\n<p>If the user is not found in OneLogin then this hook is triggered which will make a call out to Auth0 to validate the users password. </p>\n<p>If the password is valid then user details are returned, the user is created in OneLogin and the authentication is completed.</p>\n","urlObject":{"protocol":"https","path":["api","2","hooks"],"host":["{{api-domain}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"7e5bad1d-a1a6-4100-bc1b-131740c24628"},{"name":"Migrate user from AWS Cognito","event":[{"listen":"prerequest","script":{"id":"dff046a1-d744-44b5-8e70-b60d62dadbca","exec":["const functionString = `","const axios = require(\"axios\");","const jwt = require('jsonwebtoken');","const jwksClient = require('jwks-rsa');","","","function getKey(header, callback){","  var client = jwksClient({","    jwksUri: \"https://cognito-idp.\" + process.env.AWSREGION + \".amazonaws.com/\" + process.env.AWS_USERPOOLID + \"/.well-known/jwks.json\"","  });","","  client.getSigningKey(header.kid, function(err, key) {","    var signingKey = key.publicKey || key.rsaPublicKey;","    callback(null, signingKey);","  });","}","","async function verifyJWT(token) {","  return new Promise(","    (resolve, reject) => {","      jwt.verify(token, getKey, {}, function(err, decoded) {","        resolve(decoded)","      });      ","    }","  );","}","","exports.handler = async (context) => {","    // Its not considered good practice to log the user context on ","    // this hook as it contains a password. Only enable this for debugging","    // console.log(context);","","    let user;","    try {","      // Do a password grant request to validate the password","      const response = await axios.post(\"https://cognito-idp.\" + process.env.AWSREGION + \".amazonaws.com/\" , {","        AuthFlow: 'USER_PASSWORD_AUTH',","        ClientId: process.env.AWS_CLIENT_ID,","        AuthParameters: {","            USERNAME: context.user_identifier,","            PASSWORD: context.password","        }","      }, {","          headers: { ","              \"Content-Type\": \"application/x-amz-json-1.1\",","              \"X-Amz-Target\": \"AWSCognitoIdentityProviderService.InitiateAuth\"","          }","      });","      console.log(response);","    if (response.data.AuthenticationResult) {","        let decodedToken = await verifyJWT(response.data.AuthenticationResult.IdToken);","        console.log(decodedToken);","","        return {","          success: true,","          user: {","            username: context.user_identifier,","            password: context.password,","            firstname: decodedToken.given_name,","            lastname: decodedToken.family_name,","            email: decodedToken.email","          }","        };          ","      }","    }","    catch (error) {","        console.log(\"Error authenticating user \", error);         ","    }  ","    ","    // Fail closed. Dont create the user. Deny access","    return {","        success: false,","        user: {}","    }       ","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);","",""],"type":"text/javascript","packages":{}}}],"id":"af146a20-c956-4950-a497-e99019d71ca9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n\t\"type\": \"user-migration\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"context_version\": \"1.0.0\",\n\t\"retries\": 0,\n    \"runtime\": \"nodejs18.x\",\n\t\"timeout\": 10,\n\t\"env_vars\": [\n        \"AWS_USERPOOLID\",\n        \"AWS_CLIENT_ID\",\n        \"AWSREGION\"\n\t],\n\t\"packages\": {\n        \"axios\": \"0.21.1\",\n        \"jwks-rsa\": \"2.0.1\",\n        \"jsonwebtoken\": \"8.5.1\"\n\t}   \n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks","description":"<p>This user-migration hook lets you import users into OneLogin from an AWS Cognito user pool. </p>\n<p>If the user is not found in OneLogin then this hook is triggered which will make a call out to the Cognito API to validate the users password. </p>\n<p>If the password is valid then user details are returned, the user is created in OneLogin and the authentication is completed. </p>\n","urlObject":{"protocol":"https","path":["api","2","hooks"],"host":["{{api-domain}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"af146a20-c956-4950-a497-e99019d71ca9"},{"name":"Migrate user from Okta","event":[{"listen":"prerequest","script":{"id":"3776a296-c818-44c5-b08c-c032bdd209a0","exec":["const functionString = `","const axios = require(\"axios\");","","","exports.handler = async (context) => {","    // Its not considered good practice to log the user context on ","    // this hook as it contains a password. Only enable this for debugging","    // console.log(context);","","    let user;","","    try {","      // Do a password grant request to validate the password","      const response = await axios.post(\"https://\" + process.env.OKTA_SUBDOMAIN + \".okta.com/api/v1/authn\", {","          username: context.user_identifier,","          password: context.password,","          options: {","              multiOptionalFactorEnroll: false,","              warnBeforePasswordExpired: false","          } ","      }, {","          headers: { ","              \"Content-Type\": \"application/json\",","              \"Accept\": \"application/json\"","          }","      });","      console.log(response);","","      if (response.data) {","","        return {","          success: true,","          user: {","            username: context.user_identifier,","            password: context.password,","            firstname: response.data._embedded.user.profile.firstName,","            lastname: response.data._embedded.user.profile.lastName,","            email: response.data._embedded.user.profile.login","          }","        };          ","      }","    }","    catch (error) {","        console.log(\"Error authenticating user \", error);         ","    }  ","    ","    // Fail closed. Dont create the user. Deny access","    return {","        success: false,","        user: {}","    }       ","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);","",""],"type":"text/javascript","packages":{}}}],"id":"33288cea-21ef-4781-92e1-6811fb2ea6d0","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n\t\"type\": \"user-migration\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"context_version\": \"1.0.0\",\n\t\"retries\": 0,\n    \"runtime\": \"nodejs18.x\",\n\t\"timeout\": 10,\n\t\"env_vars\": [\n        \"OKTA_SUBDOMAIN\"\n\t],\n\t\"packages\": {\n        \"axios\": \"0.21.1\",\n        \"jwks-rsa\": \"2.0.1\",\n        \"jsonwebtoken\": \"8.5.1\"\n\t}   \n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks","description":"<p>This user-migration hook lets you import users into OneLogin from an Okta account. </p>\n<p>If the user is not found in OneLogin then this hook is triggered which will make a call out to Okta to validate the users password. </p>\n<p>If the password is valid then user details are returned, the user is created in OneLogin and the authentication is completed. </p>\n","urlObject":{"protocol":"https","path":["api","2","hooks"],"host":["{{api-domain}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"33288cea-21ef-4781-92e1-6811fb2ea6d0"}],"id":"5c530e97-f38d-4928-96ea-c76e62169acc","_postman_id":"5c530e97-f38d-4928-96ea-c76e62169acc","description":"","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":true,"source":{"_postman_id":"ea50e15b-7acc-4bdf-9221-1d47fc8c0550","id":"ea50e15b-7acc-4bdf-9221-1d47fc8c0550","name":"Smart Hooks - OneLogin API","type":"collection"}}},{"name":"Environment Variables","item":[{"name":"List Variables","id":"24031358-48fc-41f7-9d58-8bd65611fe6f","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"GET","header":[],"url":"https://{{api-domain}}/api/2/hooks/envs","urlObject":{"protocol":"https","path":["api","2","hooks","envs"],"host":["{{api-domain}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"24031358-48fc-41f7-9d58-8bd65611fe6f"},{"name":"Create Variable","event":[{"listen":"test","script":{"id":"80a585fb-518d-4027-b928-ece71d79d72f","exec":["pm.test(\"Status code is 201\", function () {","    pm.response.to.have.status(201);","});","","if (pm.response.json().id) {","    postman.setEnvironmentVariable(\"hook_envvar_id\", pm.response.json().id);","}"],"type":"text/javascript"}}],"id":"503b18b5-bc89-4d44-8285-2824bd1ceb35","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"name\": \"MY_API_KEY\",\n\t\"value\": \"foobarbaz\"\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/envs","urlObject":{"protocol":"https","path":["api","2","hooks","envs"],"host":["{{api-domain}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"503b18b5-bc89-4d44-8285-2824bd1ceb35"},{"name":"Update Variable","id":"fdb78338-fa46-45f1-b88b-d10492bb2443","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"value\": \"super-secret-updated\"\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/envs/:hook_env_var_id","urlObject":{"protocol":"https","path":["api","2","hooks","envs",":hook_env_var_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{hook_env_var_id}}","key":"hook_env_var_id"}]}},"response":[],"_postman_id":"fdb78338-fa46-45f1-b88b-d10492bb2443"},{"name":"Delete Variable","id":"aca2e929-4019-42ce-b2ba-a2d7e4c71b27","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"DELETE","header":[],"url":"https://{{api-domain}}/api/2/hooks/envs/:hook_env_var_id","urlObject":{"protocol":"https","path":["api","2","hooks","envs",":hook_env_var_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{hook_env_var_id}}","key":"hook_env_var_id"}]}},"response":[],"_postman_id":"aca2e929-4019-42ce-b2ba-a2d7e4c71b27"}],"id":"cae2a57a-8a77-4311-9b8a-1dc06a48ccd6","_postman_id":"cae2a57a-8a77-4311-9b8a-1dc06a48ccd6","description":"","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":true,"source":{"_postman_id":"ea50e15b-7acc-4bdf-9221-1d47fc8c0550","id":"ea50e15b-7acc-4bdf-9221-1d47fc8c0550","name":"Smart Hooks - OneLogin API","type":"collection"}}},{"name":"List Hooks","id":"f80f7d84-98e7-4eab-b967-e80dd945978b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"GET","header":[],"url":"https://{{api-domain}}/api/2/hooks","urlObject":{"protocol":"https","path":["api","2","hooks"],"host":["{{api-domain}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"f80f7d84-98e7-4eab-b967-e80dd945978b"},{"name":"Create Hook","event":[{"listen":"prerequest","script":{"id":"f8b272f8-a671-4fb3-8cd3-3ed12e24dd12","exec":["","const functionString = `","exports.handler = async (context) => {","    return {","        user: context.user","    }","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"fd7c04a0-487a-4b7f-85eb-e19412cbf750","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": false,\n    \t\"location_enabled\": false,\n        \"mfa_device_info_enabled\": false\n    },  \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks","urlObject":{"protocol":"https","path":["api","2","hooks"],"host":["{{api-domain}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"fd7c04a0-487a-4b7f-85eb-e19412cbf750"},{"name":"Get Hook","event":[{"listen":"test","script":{"id":"83f1cea7-645b-4c7d-a646-1f1a2cf6e699","exec":["// Response visualizer for showing hook content","const response = {","    ...pm.response.json(),","    function: Buffer(pm.response.json().function, 'base64').toString()","};","pm.visualizer.set(","    '<p>Function Content<p><pre><code class=\"javascript\">{{response.function}}</code></pre>',","    { response }",");"],"type":"text/javascript"}}],"id":"d829d750-5de5-4808-b3a3-83da9cd3e64e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"GET","header":[],"url":"https://{{api-domain}}/api/2/hooks/:hook_id","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"d829d750-5de5-4808-b3a3-83da9cd3e64e"},{"name":"Get Hook Logs","id":"e5cc9752-02e5-4981-85a5-9e880507e3b9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"GET","header":[],"url":"https://{{api-domain}}/api/2/hooks/:hook_id/logs","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id","logs"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"e5cc9752-02e5-4981-85a5-9e880507e3b9"},{"name":"Delete Hook","id":"b2550a3d-15b8-4930-965a-4c14385f205e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"DELETE","header":[],"url":"https://{{api-domain}}/api/2/hooks/:hook_id","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"b2550a3d-15b8-4930-965a-4c14385f205e"},{"name":"Update Hook","event":[{"listen":"prerequest","script":{"id":"c77d8764-edd0-4df1-a2e5-99ec6d92aa4c","exec":["","const functionString = `","exports.handler = async (context) => {","    return {","        user: context.user","    }","}","`;","","const b64function = Buffer.from(functionString).toString('base64');","postman.setEnvironmentVariable(\"base64Function\", b64function);",""],"type":"text/javascript","packages":{}}}],"id":"b108bc39-0555-4323-b0a1-62f324aaa423","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"type\": \"pre-authentication\",\n\t\"function\": \"{{base64Function}}\",\n\t\"disabled\": false,\n    \"runtime\": \"nodejs18.x\",\n\t\"retries\": 0,\n\t\"timeout\": 1,\n    \"options\":{\n\t    \"risk_enabled\": false,\n    \t\"location_enabled\": false,\n        \"mfa_device_info_enabled\": false\n    },  \n\t\"env_vars\": [\n\t],\n\t\"packages\": {\n\t}\n}","options":{"raw":{"language":"json"}}},"url":"https://{{api-domain}}/api/2/hooks/:hook_id","urlObject":{"protocol":"https","path":["api","2","hooks",":hook_id"],"host":["{{api-domain}}"],"query":[],"variable":[{"type":"string","value":"{{pre_authentication_hook_id}}","key":"hook_id"}]}},"response":[],"_postman_id":"b108bc39-0555-4323-b0a1-62f324aaa423"}],"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]}},"event":[{"listen":"prerequest","script":{"id":"9cf6447b-5a70-4a33-8e40-61eb89ab1e4e","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"2f0a9d0b-feec-4c54-b69b-f17a3499f9a6","type":"text/javascript","exec":[""]}}]}