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.
Confirm you want to change phone number, by pressing Change Phone Number
again.
After that, you have to enter your phone number and press Send OTP
to request for One Time Password.
Then, you will receive OTP in your phonenumber and enter the OTP to verify:
And after that, you will get confirmation saying, your phone number is verified.
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);
}
};