Skip to content

Instantly share code, notes, and snippets.

@praveen001
Last active August 12, 2023 07:49
Show Gist options
  • Save praveen001/57b0d8262e1a2ef0c539d0715a3649e1 to your computer and use it in GitHub Desktop.
Save praveen001/57b0d8262e1a2ef0c539d0715a3649e1 to your computer and use it in GitHub Desktop.
Passwordless Phone number authentication using AWS Amplify and Cognito
import Amplify, { Auth } from 'aws-amplify';
Amplify.configure({
Auth: {
region: 'us-east-1',
userPoolId: '**********',
userPoolWebClientId: '******************',
}
});
try {
const data = await Auth.currentAuthenticatedUser();
} catch {
// User not logged in
}
const AWS = require('aws-sdk');
function sendSMS(phone, code) {
const params = {
Message: code, /* required */
PhoneNumber: phone,
};
return new AWS.SNS({apiVersion: '2010-03-31'}).publish(params).promise();
}
exports.handler = async (event) => {
console.log("CUSTOM_CHALLENGE_LAMBDA", event.request);
let secretLoginCode;
if (!event.request.session || !event.request.session.length) {
// Generate a new secret login code and send it to the user
secretLoginCode = Date.now().toString().slice(-4);
try {
await sendSMS(secretLoginCode);
} catch {
// Handle SMS Failure
}
} else {
// re-use code generated in previous challenge
const previousChallenge = event.request.session.slice(-1)[0];
secretLoginCode = previousChallenge.challengeMetadata.match(/CODE-(\d*)/)[1];
}
console.log(event.request.userAttributes);
// Add the secret login code to the private challenge parameters
// so it can be verified by the "Verify Auth Challenge Response" trigger
event.response.privateChallengeParameters = { secretLoginCode };
// Add the secret login code to the session so it is available
// in a next invocation of the "Create Auth Challenge" trigger
event.response.challengeMetadata = `CODE-${secretLoginCode}`;
return event;
};
exports.handler = async (event, context, callback) => {
console.log(event.request);
// If user is not registered
if (event.request.userNotFound) {
event.response.issueToken = false;
event.response.failAuthentication = true;
throw new Error("User does not exist");
}
if (event.request.session.length >= 3 && event.request.session.slice(-1)[0].challengeResult === false) { // wrong OTP even After 3 sessions?
event.response.issueToken = false;
event.response.failAuthentication = true;
throw new Error("Invalid OTP");
} else if (event.request.session.length > 0 && event.request.session.slice(-1)[0].challengeResult === true) { // Correct OTP!
event.response.issueTokens = true;
event.response.failAuthentication = false;
} else { // not yet received correct OTP
event.response.issueTokens = false;
event.response.failAuthentication = false;
event.response.challengeName = 'CUSTOM_CHALLENGE';
}
return event;
};
exports.handler = async (event) => {
event.response.autoConfirmUser = true;
event.response.autoVerifyPhone = true;
return event;
};
try {
const cognitoUser = await Auth.signIn(phoneNumber);
} catch {
// Handle sign in errors
}
try {
await Auth.signUp({
username: phoneNumber,
password: Date.now().toString()
});
} catch {
// Handle sign up error
}
try {
const cognitoUser = await Auth.sendCustomChallengeAnswer(user, OTP);
} catch {
// Handle 3 error thrown for 3 incorrect attempts.
}
exports.handler = async (event) => {
console.log(event.request);
const expectedAnswer = event.request.privateChallengeParameters.secretLoginCode;
if (event.request.challengeAnswer === expectedAnswer) {
event.response.answerCorrect = true;
} else {
event.response.answerCorrect = false;
}
return event;
};
@orr-levinger
Copy link

how can i test it? is there a way as an admin to not send SMS so i can test my api with mocha?
also would this still work with my facebook login or will the triggers break the facebook flow?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment