SPRINT 4 ‐ Phone Number Verification - BlueJayBird11/UniJet GitHub Wiki

As a developer, I have verified phone numbers of my users for functional and security purposes.

About Phone Number Verification

For safety of our users, we have also included the functionality of verifying phone numbers. Phone number Verification comes up when you try to change your phone number from Settings Menu.

Usage

To change phone number, you need to go to settings page, click on Change Phone Number button.

image

Confirm you want to change phone number, by pressing Change Phone Number again.

image

After that, you have to enter your phone number and press Send OTP to request for One Time Password.

image

Then, you will receive OTP in your phonenumber and enter the OTP to verify:

image

And after that, you will get confirmation saying, your phone number is verified.

image

Workings

The inner working of these features are divided into two parts, backend and frontend.

backend

The backend working for generating and sending OTP are located in smsVerification.ts inside backend_ts. We are using Twilio Api to send the SMS verification. The .env file, which contains Twilio information for our website is not to be pushed in github repo for public to see. The code used for sending OTP and verifying OTP are very similar, the one notable difference is in sending OTP. For sending the OTP we call Twilio API. Below is the snippet of code associated with it:

const twilioClient = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);


const message = await twilioClient.messages.create({
                    body: `Your OTP is: ${otp}. If you did not request this, please ignore this message. Unijet`,
                    from: process.env.TWILIO_PHONE_NUMBER,
                    to: phoneNumber,
                });

                if (message.sid) {
                    res.json({ message: 'OTP sent successfully to phone.' });
                } else {
                    throw new Error('Failed to send OTP');
                }
            } catch (error) {
                console.error('Error sending SMS:', error);
                const errorMessage = error instanceof Error ? error.message : 'Failed to send OTP to phone.';
                res.status(500).json({ error: errorMessage });
            }

frontend

The file associated with sending OTP & verify phone numbers for frontend are located in Unijet/frontend/src/scenes/settings/phoneNumber/

This is the snippet of code that handles sending the OTP by calling the backend:

    const handleSendOtp = async () => {
        if (!phoneNumber || phoneNumber.length < 10) {
            alert('Please enter a valid phone number');
            return;
        }
        try {
            const response = await axios.post('http://localhost:8000/api/send-phone-otp', { phoneNumber });
            if (response.status === 200) {
                console.log('OTP sent successfully:', response.data.message);
                setOtpSent(true); // OTP was successfully sent
            } else {
                throw new Error(response.data.error || 'Failed to send OTP');
            }
        } catch (error: any) {
            console.error('Error sending OTP:', error);
            alert((error.response?.data?.error || 'Failed to send OTP') as string);
            setOtpSent(false); // Failed to send OTP
        }
    };

And this is the snippet of code that handles verifying OTP by calling the backend:

    const handleVerifyOtp = async () => {
        if (!phoneOtp || phoneOtp.length !== 6) {
            alert('Please enter the 6-digit OTP');
            return;
        }
        try {
            const response = await axios.post('http://localhost:8000/api/verify-phone-otp', { phoneNumber, otp: phoneOtp });
            if (response.status === 200) {
                setIsPhoneVerified(true);
                console.log('Phone number verified:', response.data.message);
                setOtpSent(false); // Reset OTP sent status after successful verification
                setEditMode(false); // Exit edit mode after successful verification
            } else {
                throw new Error(response.data.error || 'OTP verification failed');
            }
        } catch (error: any) {
            console.error('Error verifying OTP:', error);
            setOtpError((error.response?.data?.error || 'Failed to verify OTP') as string);
        }
    };