Open fahadsadiq opened 3 months ago
The trick is to pass the right thing into the smsMfaCode
prop: you need to pass in a function that will return a promise that will resolve to the OTP that the user entered. Create a custom promise for that.
For example, let's presume you have this form:
<form id="myForm">
<label for="otp">OTP:</label>
<input type="text" id="otp" name="otp" required>
<button type="submit">Submit</button>
</form>
Then this is how your "promisify" the input and wire it into the lib:
import { stepUpAuthenticationWithSmsOtp } from "amazon-cognito-passwordless-auth/sms-otp-stepup";
function createSmsOtpPromise() {
// return custom promise:
return new Promise((resolve, reject) => {
const form = document.querySelector("#myForm");
form.addEventListener('submit', function(event) {
event.preventDefault();
const otp = new FormData(form).get('otp');
resolve(otp);
}, { once: true }); // Listener is removed after execution
});
}
// call the SMS OTP Function
const { signedIn, abort } = stepUpAuthenticationWithSmsOtp({
username: "john",
smsMfaCode: createSmsOtpPromise,
}
The signature of the smsMfaCode
function is actually: (phoneNumber: string, attempt: number) => Promise<string>
but in the above example I don't use phoneNumber
and attempt
. When the library calls createOtpPromise
it will pass in the phone number that the OTP was sent to, as well as the nr of times the user has already tried, but you don't need to use these per se, but could be nice to show to the user. Then you need a bit more coding to show these values to the user.
Let me know if that helps!
Thank you for the help. Though the issue i am facing is a bit different i feel. I have created a demo application for this functionality.
<script lang="ts">
import { stepUpAuthenticationWithSmsOtp } from 'amazon-cognito-passwordless-auth/sms-otp-stepup';
import type { TokensFromStorage } from 'amazon-cognito-passwordless-auth/storage';
import { getContext } from 'svelte';
const tokens = getContext<TokensFromStorage>('session');
$: otp = '';
async function createSmsOtp() {
return otp;
}
function handleStepUpAuthentication() {
const { signedIn, abort } = stepUpAuthenticationWithSmsOtp({
username: 'test',
accessToken: tokens.accessToken,
smsMfaCode: createSmsOtp
});
}
</script>
<div>
<button type="submit" on:click={handleStepUpAuthentication}>Step up Auth</button>
<input type="text" bind:value={otp} />
<button type="button" on:click={createSmsOtp}>Submit</button>
</div>
This is a basic svelte file that i have created. In this component, when i click on step up auth button stepUpAuthenticationWithSmsOtp is called. Instead of just sending the sms OTP, it does 4 calls on of which is a submit call for otp. I have attached a vide os the same.
If there a way to use the functionality using functions instead of form on submit?
You need to pass a function that return a promise that only resolves once the user actually submits the OTP. I think your promise immediately resolves with an empty value, and does that 3 times in a row until the custom auth flow says "nope, no more attempts for you".
I lack the Vue knowledge to help you but it should be close enough to the createSmsOtpPromise
function example above
Guessing, but something like this:
<script lang="ts">
import { stepUpAuthenticationWithSmsOtp } from 'amazon-cognito-passwordless-auth/sms-otp-stepup';
import type { TokensFromStorage } from 'amazon-cognito-passwordless-auth/storage';
import { getContext } from 'svelte';
const tokens = getContext<TokensFromStorage>('session');
let submitOtp: (otp: string) => void;
const smsMfaCode = () => new Promise<string>(resolve => submitOtp = resolve);
$: otp = '';
function handleStepUpAuthentication() {
const { signedIn, abort } = stepUpAuthenticationWithSmsOtp({
username: 'test',
accessToken: tokens.accessToken,
smsMfaCode,
});
}
</script>
<div>
<button type="submit" on:click={handleStepUpAuthentication}>Step up Auth</button>
<input type="text" bind:value={otp} />
<button type="button" on:click={submitOtp}>Submit</button>
</div>
Did that help @fahadsadiq ? How's it going?
Hello, I want to implement step up auth with SMS on some of the pages when a user is logged in. The application that we are using it in is svelte. We tried to re-enact the same login as in react end to end example for step up auth but we are not able to do the same procedure. When calling the function, the following api's are called:
Could you please shine some light on how we would implement the same in plain web without the await able state that you have used in react.