javascriptandroidreactjsautofillionic-react

Autoread OTP in web and copy paste OTP from clipboard in web not working for android/iOS


I'm using Ionic React application and completely new to building ionic react apps. Currently I'm trying to autofill OTP(One Time Password) by fetching the OTP through message's of android/iOS during the login/signup of user. Currently the OTP is being sent to user on every new signup /login through Twilio's default SMS service. So when the OTP arrives to the user , then the user can either type the OTP manually or copy the OTP from messages and paste the same in the web application. So currently the user is able copy the OTP from message and paste ( there is handlePaste function which will get triggered ), but the

Issue what I'm facing

SMS FORMAT

Your OTP is: 123456.

@domain.com #123456

Approaches tried so far :

handlePaste function code :

const length = 6;
const [activeInput, setActiveInput] = useState(0)
const [otpValues, setOTPValues] = useState(Array<string>(length).fill(''))


    const handleOnPaste = 
    (e: React.ClipboardEvent<HTMLInputElement>) => {
        e.preventDefault()
        const pastedData = e.clipboardData
            .getData('text/plain')
            .trim()
            .slice(0, length - activeInput)
            .split('')
        if (pastedData) {
            let nextFocusIndex = 0
            const updatedOTPValues = [...otpValues]
            updatedOTPValues.forEach((val, index) => {
                
                    console.log(pastedData)
                        nextFocusIndex = index
                    
                
            })
            setActiveInput(Math.min(nextFocusIndex + 1, length - 1))
        }
    }

Navigator credentials code which is used inside the function but didn't work :

navigator.credentials.get({
  otp: { transport:['sms'] },
  signal: ac.signal
}).then((otp) => {
  console.log(otp)
  
}).catch((err) => {
  console.error(err);
});


I would really appreciate if someone could help me out :)


Solution

  • The Problem actually is with web browser of iOS/android phones. In mobile web browsers the onPaste function never gets triggered when the text/number is paste from keyboard clipboard. Which looks something like this.

    AutoRead OTP from messages

    So in short your handlePaste function never gets triggered and your clipboardData never gets value inside it but your onchange function of input element gets triggered.

    SOLUTION :

    1. What you can do is , inside your onChange function check for the input value.
    2. Check if the value length is greater than 1.
    3. If it is greater than 1 , then manually add the data into clipboardData.
    4. Then call the handlePaste function.

    Code :

    Add this in your onChange function.

    const handleChange = (e) => {
      const val = e.target.value;
    
      if (!val) {
        e.preventDefault();
        return;
      }
    
      // add this condition to manually trigger the paste
      // function and manually send the value to clipboard
    
      else if (val.trim().length > 1) {
        e.clipboardData = {
          getData: () => val.trim(),
        };
        handleOnPaste(e);
      } else {
    
        // do any other required changes
      }
    };
    
    
    

    This will solve your issue of OTP only gets filled in Single input.