Last active
August 4, 2023 03:45
-
-
Save mobilequickie/202a7dd1f72a2440b140f9bf44e6e46f to your computer and use it in GitHub Desktop.
Amazon Cognito CUSTOM_CHALLENGE Lambda trigger - Create Auth Challenge function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ### About this Flow ### | |
// Using Custom Auth Flow through Amazon Cognito User Pools with Lambda Triggers to complete a 'CUSTOM_CHALLENGE'. | |
// | |
// ### About this function ### | |
// This CreateAuthChallengeSMS function (2nd of 4 triggers) creates the type of 'CUSTOM_CHALLENGE' as a one-time pass code sent via SMS. A one-time randomly generated 6-digit code (passCode) | |
// is sent via SMS (through Amazon SNS) to the user's mobile phone number during authentication. The generated passCode is stored in privateChallengeParameters.passCode and passed to the VerifyAuthChallenge function | |
// that will verify the user's entered passCode (received via SMS) into the mobile/web app matches the passCode passed privately through privateChallengeParameters.passCode. | |
// ### Next steps ### | |
// Instead of using the "crypto-secure-random-digit" library to generate random 6-digit codes, create a base32 secret for the user (if not exist) and | |
// generate a 6-digit code based on this secret. Much like TOTP except for the secret is never shared with the user. With a base32 secret associated with the user, | |
// we can easily switch from 6-digit code via SMS to 6-digit code generated based on shared secret via TOTP using the OATH module of a YubiKey or an authenticator app. | |
// | |
// Updated: Jan 6, 2020 | |
'use strict'; | |
const crypto_secure_random_digit = require("crypto-secure-random-digit"); | |
const AWS = require("aws-sdk"); | |
var sns = new AWS.SNS(); | |
// Main handler | |
exports.handler = async (event = {}) => { | |
console.log('RECEIVED event: ', JSON.stringify(event, null, 2)); | |
let passCode; | |
var phoneNumber = event.request.userAttributes.phone_number; | |
// The first CUSTOM_CHALLENGE request for authentication from | |
// iOS AWSMobileClient actually comes in as an "SRP_A" challenge (a bug in the AWS SDK for iOS?) | |
// web (Angular) comes in with an empty event.request.session | |
if (event.request.session && event.request.session.length && event.request.session.slice(-1)[0].challengeName == "SRP_A" || event.request.session.length == 0) { | |
passCode = crypto_secure_random_digit.randomDigits(6).join(''); | |
await sendSMSviaSNS(phoneNumber, passCode); | |
} else { | |
const previousChallenge = event.request.session.slice(-1)[0]; | |
passCode = previousChallenge.challengeMetadata.match(/CODE-(\d*)/)[1]; | |
} | |
event.response.publicChallengeParameters = { phone: event.request.userAttributes.phone_number }; | |
event.response.privateChallengeParameters = { passCode }; | |
event.response.challengeMetadata = `CODE-${passCode}`; | |
console.log('RETURNED event: ', JSON.stringify(event, null, 2)); | |
return event; | |
}; | |
// Send secret code over SMS via Amazon Simple Notification Service (SNS) | |
async function sendSMSviaSNS(phoneNumber, passCode) { | |
const params = { "Message": "[MobileQuickie] Your secret code: " + passCode, "PhoneNumber": phoneNumber }; | |
await sns.publish(params).promise(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment