Email Verification for an Android App Registration System

In a previous tutorial titled Building an Android Login System, we created an Android login system, which allows the user to register by their first name, last name, username, and password. A Flask server listens for requests from the user and inserts a new record in a MySQL database. After successful registration, the user can log in and be verified by the server.

This tutorial extends upon the previous tutorial to allow users to enter an email address while registering. To verify the ownership of the entered email address, an email is sent to this address with a verification code. The user copies the code sent in the email and pastes it into the application to complete the email verification process.

Once the email address is verified successfully, a new record is added to the MySQL database for the user. The verified email address can be used for future communications with the user and for resetting their password.

The sections covered in this tutorial are as follows:

  • Adding a Column in the Database Table for Email
  • Sending Emails using Python
  • Verification Code
  • Text Encryption
  • Generating Encryption Keys
  • Verifying Code
  • Text Decryption
  • Adding an EditText for Email in the Android App

The GitHub project for this tutorial is available here.

The content of this tutorial is applied to a live application in the Google Play Store named HiAi Chat, available here.

Let’s get started.

Adding a Column in the Database Table for Email

In the previous tutorial, a database named chat_db was created. The database just has a single table named users for holding registered user data. The users table has the following columns:

  • id
  • firstname
  • lastname
  • username
  • password
  • registration_date

We’re going to add a new column in the users table named email. There’s no need to delete the previous table to add a new column because we can do it using an ALTER TABLE operation. The Python code used for adding the new column is shown below:

import mysql.connector
import sys

try:
    chat_db = mysql.connector.connect(host="localhost", user="root", passwd="ahmedgad", database="chat_db")
except:
    sys.exit("Error connecting to the database. Please check your inputs.")

db_cursor = chat_db.cursor()

add_column_query = "ALTER TABLE users ADD email VARCHAR(255) NOT NULL UNIQUE"
db_cursor.execute(add_column_query)
chat_db.commit()

At this time, the email column is added to the users table. Next, we’ll look at sending emails using Python. Once we’re able to send emails, we can send verification codes to verify user accounts.

Sending E-mails using Python

Python provides a library named smtp for sending emails. The following function named send_email is used for this. The function accepts 3 arguments:

  1. subject: Message subject
  2. body: Message body
  3. email: Receiver email entered by the user

To make this function work, we need to edit the following 4 variables within the function:

  1. port: Port used for sending the emails via the server.
  2. smtp_server: The server based on your mailing system. For example, if Gmail is used, then set its value to smtp.gmail.com.
  3. sender_email: The email address from which the message will be sent.
  4. password: Email password
def send_email(subject, body, email):
    port = 465
    smtp_server = "hiai.website"
    sender_email = "[email protected]"
    password = "..."

    msg_body = body
    
    msg = MIMEText(msg_body, 'plain', 'utf-8')

    # add in the actual person name to the message template
    msg['From'] = sender_email
    msg['To'] = email
    msg['Subject'] = subject

    context = ssl.create_default_context()
    with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:
        server.login(sender_email, password)
        server.sendmail(sender_email, email, msg.as_string())

Once we can send emails, we then need to be able to send verification codes to the e-mail addresses entered in the registration form.

Verification Code

Based on what we learned in the previous tutorial, when a user clicks the Register button in the Android app, that user’s inputs are sent to the server, and a new record is added to the database if the username doesn’t exist.

In this tutorial, there is a slight modification after adding the email column to the users table. When the server receives the registration request, the register() function listed below will be executed. This function does 2 tasks:

  1. Ensures the username and the email are not used by another user. This is done by selecting the records from the users table where the username column is equal to the current username or the email column is equal to the current email.
  2. Calls a function named send_verification_code() for sending the verification code.
def register(msg_received):
    first_name = msg_received["first_name"]
    lastname = msg_received["last_name"]
    username = msg_received["username"]
    email = msg_received["email"]

    select_query = "SELECT * FROM users where username = " + "'" + username + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) != 0:
        return "username" # "Username already exists. Please chose another username."

    select_query = "SELECT * FROM users where email = " + "'" + email + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) != 0:
        return "email" # "E-mail is already registered."

    send_verification_code(first_name, lastname, username, email) # Encrypt e-mail using 2 keys and send the code to the user e-mail.

    return "success"

The implementation of the send_verification_code() function is listed below. All it does is call a function named encrypt_text() that encrypts the email address entered by the user. After that, the email body is prepared, in which the encrypted email is embedded. Finally, the email is sent using the send_email() function discussed previously. Let’s discuss how the encrypt_text() function is implemented.

def send_verification_code(firstname, lastname, username, email):
    
    encrypted_email = encrypt_text(email)
    
    body = "Hi " + firstname + " " + lastname + ",nnThanks for registering for HiAi Chat System.nnYour username is " + username + ".nTo verify your account, just copy the verification code found below, return back to the Android app, paste the code, and finally click the Verify button.nnn" + encrypted_email.decode()
    subject = "HiAi Verification"

    send_email(subject, body, email)

Text Encryption

The implementation of the encrypt_text() function is shown below. It accepts the text to be encrypted as input and returns the encrypted text. How does this encryption takes place? This is done by using a library called cryptography. This library has an implementation of the AES encryption algorithm named Fernet. It’s implemented in the cryptography.fernet.Fernet class.

def encrypt_text(text_to_encrypt):
    key_file1 = open("encryption_key1.key", "rb")
    encryption_key1 = key_file1.read()
    key_file1.close()
    
    key_file2 = open("encryption_key2.key", "rb")
    encryption_key2 = key_file2.read()
    key_file2.close()

    encoded_email = text_to_encrypt.encode()

    f = cryptography.fernet.MultiFernet([cryptography.fernet.Fernet(encryption_key1), cryptography.fernet.Fernet(encryption_key2)])
    
    encrypted_text = f.encrypt(encoded_email)
    
    return encrypted_text

Generating Encryption Keys

In order to encrypt a message, we must first generate an encryption key. A key can be generated using the cryptography.fernet.Fernet.generate_key() function.

In the above function, 2 keys are used to make it difficult for hackers to break the encryption. The keys can be generated using the code listed below. Each key is saved in a different file. The first key is saved in the encryption_key1.key file, while the second one is saved in the encryption_key2.key file.

Once the keys are generated, you have to keep them secure because they will be used for encrypting and decrypting all emails.

import cryptography.fernet

encryption_key1 = cryptography.fernet.Fernet.generate_key()
print("Encryption Key 1 :", encryption_key1)

key_file1 = open("encryption_key1.key", "wb")
key_file1.write(encryption_key1)
key_file1.close()

encryption_key2 = cryptography.fernet.Fernet.generate_key()
print("Encryption Key 2 :", encryption_key2)

key_file2 = open("encryption_key2.key", "wb")
key_file2.write(encryption_key2)
key_file2.close()

The cryptography library allows using more than one key simultaneously using the cryptography.fernet.MultiFernet class. Using the encrypt() method, the e-mail will be encrypted and returned via the encrypt_text() function.

Assume that the email to be encrypted is [email protected]. If the 2 keys are as follows:

  1. lGb0Xm-saWeojY9uIrKfZ9xwDDV1RSUr2AkCAgTAnuY=
  2. uR8FMwt-2I05eR5ggmRlqX_um20zR7x1EQDTvNH7esU=

Then the encrypted email is as follows:

gAAAAABdn0PCEuEAJ0GOixRJ48Lr7skDO0y7jtvNION0hP1oIsoI45nXq5OgxmU43Fs26cZu2tsMLCnbtzLPOkqmFEM7hTL8LUaQDNDB223Mq3E-OfErgUE=

The encrypted email is inserted in a message to the user. According to the send_verification_code() function, the message is as follows—assuming the first name is Ahmed, last name is Gad, and username is ahmedgad.

Verification Code

As instructed in the email, the user has to copy the verification code, go the Android app, paste the code there, and then click the Verify button to send the verification code to the server.

The server verifies the email address using the verify() function shown below. At first, it fetches the fields entered during registration and makes sure the username and the email fields are not used by another user. We did that previously in the register() function, but another user might have been able to use either the username or the password in the time it takes to copy and paste the verification code.

def verify(msg_received):
    firstname = msg_received["firstname"]
    lastname = msg_received["lastname"]
    username = msg_received["username"]
    email = msg_received["email"]
    password = msg_received["password"]
    verification_code = msg_received["verification_code"]

    select_query = "SELECT * FROM users where username = " + "'" + username + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) != 0:
        return "Another user just used the username. Please chose another username."

    select_query = "SELECT * FROM users where email = " + "'" + email + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) != 0:
        return "Another user just registered using the e-mail entered."

    verification_state = verify_code(email, verification_code)

    if verification_state == True:
        insert_query = "INSERT INTO users (first_name, last_name, username, email, password, email_confirmed) VALUES (%s, %s, %s, %s, MD5(%s), %s)"
        insert_values = (firstname, lastname, username, email, password, True)
        try:
            db_cursor.execute(insert_query, insert_values)
            chat_db.commit()
            print("This e-mail", email, " is verified and user is registered successfully.")
            subject = "Welcome to HiAi"
            body = "Hi " + firstname + " " + lastname + ",nnYour account is created successfully at HiAi. You can login with your username and password into the Android app to send and receive messages. nnYour username is " + username + "nnIf you forgot your password, just contact [email protected] for resetting it. nnGood luck.nHiAi [email protected]"
            send_email(subject, body, email)
            return "success"
        except Exception as e:
            print("Error while inserting the new record :", repr(e))
            return "Error while processing the request."
    else:
        print("This e-mail", email, " verification failed.")
        return "failure"

If the username and the email are still available, then the verification code pasted by the user will be verified using the verify_code() function, which is shown below. It decrypts the email address using a function named decrypt_text().

If the decoded e-mail matches the e-mail address entered by the user, then verification is completed successfully and the verify_code() function will return True. Otherwise, it returns False.

If True is returned, then the verify() function will insert a new record in the database for the user and then send an email that informs the user that the registration has completed successfully.

def verify_code(email, verification_code):
    decoded_email = decrypt_text(verification_code)
    if decoded_email == email:
        return True # Email verification succeeded.
    else:
        return False # Email verification failed.

Text Decryption

At the server, the verification code is decrypted using the decrypt_text() function. Similar to the encrypt_text() function, it reads the 2 keys and creates an instance of the cryptography.fernet.MultiFernet class. For decryption, the decrypt() function is used, and the decrypted text is returned.

def decrypt_text(text_to_decrypt):
    key_file1 = open("encryption_key1.key", "rb")
    encryption_key1 = key_file1.read()
    key_file1.close()
    
    key_file2 = open("encryption_key2.key", "rb")
    encryption_key2 = key_file2.read()
    key_file2.close()
    
    f = cryptography.fernet.MultiFernet([cryptography.fernet.Fernet(encryption_key1), cryptography.fernet.Fernet(encryption_key2)])
    try:
        decrypted_text = f.decrypt(text_to_decrypt.encode('utf-8'))
    except:
        return False # Email verification failed.
    decoded_text = decrypted_text.decode()
    return decoded_text

At this time, the server is able to verify the email address. The complete code of the server is shown below.

import flask
import mysql.connector
import sys
import smtplib, ssl
from email.mime.text import MIMEText
import cryptography.fernet
app = flask.Flask(__name__)
@app.route('/', methods = ['GET', 'POST'])
def chat():
    msg_received = flask.request.get_json()
    msg_subject = msg_received["subject"]
    if msg_subject == "register":
        return register(msg_received)
    elif msg_subject == "login":
        return login(msg_received)
    elif msg_subject == "verify":
        return verify(msg_received)
    else:
        return "Invalid request."
def register(msg_received):
    first_name = msg_received["first_name"]
    lastname = msg_received["last_name"]
    username = msg_received["username"]
    email = msg_received["email"]
    select_query = "SELECT * FROM users where username = " + "'" + username + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) != 0:
        return "username" # "Username already exists. Please chose another username."
    select_query = "SELECT * FROM users where email = " + "'" + email + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) != 0:
        return "email" # "E-mail is already registered."
    send_verification_code(first_name, lastname, username, email) # Encrypt e-mail using 2 keys and send the code to the user e-mail.
    return "success"
def verify(msg_received):
    firstname = msg_received["firstname"]
    lastname = msg_received["lastname"]
    username = msg_received["username"]
    email = msg_received["email"]
    password = msg_received["password"]
    verification_code = msg_received["verification_code"]
    select_query = "SELECT * FROM users where username = " + "'" + username + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) != 0:
        return "Another user just used the username. Please chose another username."
    select_query = "SELECT * FROM users where email = " + "'" + email + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) != 0:
        return "Another user just registered using the e-mail entered."
    verification_state = verify_code(email, verification_code)
    if verification_state == True:
        insert_query = "INSERT INTO users (first_name, last_name, username, email, password, email_confirmed) VALUES (%s, %s, %s, %s, MD5(%s), %s)"
        insert_values = (firstname, lastname, username, email, password, True)
        try:
            db_cursor.execute(insert_query, insert_values)
            chat_db.commit()
            print("This e-mail", email, " is verified and user is registered successfully.")
            subject = "Welcome to HiAi"
            body = "Hi " + firstname + " " + lastname + ",nnYour account is created successfully at HiAi. You can login with your username and password into the Android app to send and receive messages. nnYour username is " + username + "nnIf you forgot your password, just contact [email protected] for resetting it. nnGood luck.nHiAi [email protected]"
            send_email(subject, body, email)
            return "success"
        except Exception as e:
            print("Error while inserting the new record :", repr(e))
            return "Error while processing the request."
    else:
        print("This e-mail", email, " verification failed.")
        return "failure"
def verify_code(email, verification_code):
    decoded_email = decrypt_text(verification_code)
    if decoded_email == email:
        return True # Email verification succeeded.
    else:
        return False # Email verification failed.
def encrypt_text(text_to_encrypt):
    key_file1 = open("encryption_key1.key", "rb")
    encryption_key1 = key_file1.read()
    key_file1.close()
    
    key_file2 = open("encryption_key2.key", "rb")
    encryption_key2 = key_file2.read()
    key_file2.close()
    encoded_email = text_to_encrypt.encode()
    f = cryptography.fernet.MultiFernet([cryptography.fernet.Fernet(encryption_key1), cryptography.fernet.Fernet(encryption_key2)])
    
    encrypted_text = f.encrypt(encoded_email)
    
    return encrypted_text
def decrypt_text(text_to_decrypt):
    key_file1 = open("encryption_key1.key", "rb")
    encryption_key1 = key_file1.read()
    key_file1.close()
    
    key_file2 = open("encryption_key2.key", "rb")
    encryption_key2 = key_file2.read()
    key_file2.close()
    
    f = cryptography.fernet.MultiFernet([cryptography.fernet.Fernet(encryption_key1), cryptography.fernet.Fernet(encryption_key2)])
    try:
        decrypted_text = f.decrypt(text_to_decrypt.encode('utf-8'))
    except:
        return False # Email verification failed.
    decoded_text = decrypted_text.decode()
    return decoded_text
def send_verification_code(firstname, lastname, username, email):
    
    encrypted_email = encrypt_text(email)
    
    body = "Hi " + firstname + " " + lastname + ",nnThanks for registering for HiAi Chat System.nnYour username is " + username + ".nTo verify your account, just copy the verification code found below, return back to the Android app, paste the code, and finally click the Verify button.nnn" + encrypted_email.decode()
    subject = "HiAi Verification"
    send_email(subject, body, email)
def login(msg_received):
    username = msg_received["username"]
    password = msg_received["password"]
    select_query = "SELECT first_name, last_name FROM users where username = " + "'" + username + "' and password = " + "MD5('" + password + "')"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) == 0:
        return "failure"
    else:
        return "success"
def send_email(subject, body, email):
    port = 465  # For SSL
    smtp_server = "hiai.website"
    sender_email = "[email protected]"  # Enter your address
    password = "..."
    msg_body = body
    
    msg = MIMEText(msg_body, 'plain', 'utf-8')
    # add in the actual person name to the message template
    msg['From'] = sender_email
    msg['To'] = email
    msg['Subject'] = subject
    context = ssl.create_default_context()
    with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:
        server.login(sender_email, password)
        server.sendmail(sender_email, email, msg.as_string())
try:
    chat_db = mysql.connector.connect(host="localhost", user="root", passwd="ahmedgad", database="chat_db")
except:
    sys.exit("Error connecting to the database. Please check your inputs.")
db_cursor = chat_db.cursor()
app.run(host="0.0.0.0", port=5000, debug=True, threaded=True) # Run in development server.

After the server is prepared, the next step is to edit the Android app by adding a field for the user to enter the email address and submit the verification code.

Adding an EditText View for E-mail in the Android App

The layout of the Register activity is edited to allow adding new views for the email and the verification code. The XML layout is shown below:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <EditText
        android:id="@+id/firstName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:digits="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
        android:hint="First Name"
        android:singleLine="true"
        android:textStyle="bold" />
    <EditText
        android:id="@+id/lastName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:digits="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
        android:hint="Last Name"
        android:singleLine="true"
        android:textStyle="bold" />
    <EditText
        android:id="@+id/username"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:digits="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        android:hint="Username"
        android:singleLine="true"
        android:textStyle="bold" />
    <EditText
        android:id="@+id/email"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="E-mail"
        android:inputType="textEmailAddress"
        android:singleLine="true"
        android:textStyle="bold" />
    <EditText
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Password"
        android:inputType="textPassword"
        android:singleLine="true"
        android:textStyle="bold" />
    <Button
        android:id="@+id/registerButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#D7E2B8"
        android:onClick="register"
        android:text="Register"
        android:textStyle="bold" />
    <TextView
        android:id="@+id/responseTextRegister"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text=""
        android:textAlignment="center"
        android:textColor="#FF0000"
        android:textStyle="bold" />
    <EditText
        android:id="@+id/verificationCode"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:enabled="false"
        android:hint="Paste Verification Code"
        android:inputType="text"
        android:singleLine="true"
        android:textStyle="bold" />
    <Button
        android:id="@+id/verifyButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#D7E2B8"
        android:enabled="false"
        android:onClick="verifyEmail"
        android:text="Confirm"
        android:textStyle="bold" />
</LinearLayout>

The screen of the Register activity is shown below. You can see that that the EditText view of the verification code and the CONFIRM button aren’t enabled. They will be enabled only after the server sends the verification code.

When the REGISTER button is clicked, the register() method is called. It fetches the values from the registration form and prepares a JSON object with such values. Because our target is to register a new user, then the subject field of the JSON object is set to register. After the JSON object is created, the postRequest() method is used to create and send an HTTP post to the server.

public void register(View v) {
        EditText emailView = findViewById(R.id.email);
        EditText usernameView = findViewById(R.id.username);
        EditText firstNameView = findViewById(R.id.firstName);
        EditText lastNameView = findViewById(R.id.lastName);
        String email = emailView.getText().toString().trim();
        String username = usernameView.getText().toString().trim();
        String firstName = firstNameView.getText().toString().trim();
        String lastName = lastNameView.getText().toString().trim();
        if (email.length() == 0 || username.length() == 0) {
            Toast.makeText(getApplicationContext(), "Something is wrong. Please check your inputs.", Toast.LENGTH_LONG).show();
        } else {
            JSONObject registrationForm = new JSONObject();
            try {
                registrationForm.put("subject", "register");
                registrationForm.put("email", email);
                registrationForm.put("first_name", firstName);
                registrationForm.put("last_name", lastName);
                registrationForm.put("username", username);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), registrationForm.toString());
            registerPost = true;
            postRequest(MainActivity.postUrl, body);
        }
    }

After the server receives the registration request, it sends a verification code to the entered email. Once the message is sent, it responds to the Android app to inform it the registration is pending the email address verification, and both the EditText and the Button of the verification will be enabled. This is shown below.

Once the CONFIRM button is clicked, the verifyEmail() method is called, which is also implemented as below. Similar to the register() method, it fetches the values from all fields in addition to getting the pasted verification code. After that, a JSON object is prepared and its subject is now set to verify. Finally, the postRequest() method is called to create and send an HTTP request to the server.

public void verifyEmail(View v) {
        EditText verificationCodeView = findViewById(R.id.verificationCode);
        EditText firstNameView = findViewById(R.id.firstName);
        EditText lastNameView = findViewById(R.id.lastName);
        EditText emailView = findViewById(R.id.email);
        EditText usernameView = findViewById(R.id.username);
        EditText passwordView = findViewById(R.id.password);
        String verificationCode = verificationCodeView.getText().toString().trim();
        String firstName = firstNameView.getText().toString().trim();
        String lastName = lastNameView.getText().toString().trim();
        String email = emailView.getText().toString().trim();
        String username = usernameView.getText().toString().trim();
        String password = passwordView.getText().toString().trim();
        if (firstName.length() == 0 || lastName.length() == 0 || email.length() == 0 || username.length() == 0 || password.length() == 0) {
            Toast.makeText(getApplicationContext(), "Something is wrong. Please check your inputs.", Toast.LENGTH_LONG).show();
        } else {
            JSONObject registrationForm = new JSONObject();
            try {
                registrationForm.put("subject", "verify");
                registrationForm.put("verification_code", verificationCode);
                registrationForm.put("firstname", firstName);
                registrationForm.put("lastname", lastName);
                registrationForm.put("email", email);
                registrationForm.put("username", username);
                registrationForm.put("password", password);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), registrationForm.toString());
            verifyPost = true;
            postRequest(MainActivity.postUrl, body);
        }
    }

When the valid verification code is entered, then the server registers the user successfully, as shown in the Toast message printed in the next figure.

After that, you can login with the new username and password, as shown below.

The entire implementation of the Register activity is listed below, within which the postRequest() is implemented.

package gad.hiai.chat.hiaichat;
import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class RegisterActivity extends AppCompatActivity {
    private static boolean registerPost = false;
    private static boolean verifyPost = false;
    private Context registerActivityContext;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        registerActivityContext = this;
    }
    public void register(View v) {
        EditText emailView = findViewById(R.id.email);
        EditText usernameView = findViewById(R.id.username);
        EditText firstNameView = findViewById(R.id.firstName);
        EditText lastNameView = findViewById(R.id.lastName);
        String email = emailView.getText().toString().trim();
        String username = usernameView.getText().toString().trim();
        String firstName = firstNameView.getText().toString().trim();
        String lastName = lastNameView.getText().toString().trim();
        if (email.length() == 0 || username.length() == 0) {
            Toast.makeText(getApplicationContext(), "Something is wrong. Please check your inputs.", Toast.LENGTH_LONG).show();
        } else {
            JSONObject registrationForm = new JSONObject();
            try {
                registrationForm.put("subject", "register");
                registrationForm.put("email", email);
                registrationForm.put("first_name", firstName);
                registrationForm.put("last_name", lastName);
                registrationForm.put("username", username);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), registrationForm.toString());
            registerPost = true;
            postRequest(MainActivity.postUrl, body);
        }
    }
    public void verifyEmail(View v) {
        EditText verificationCodeView = findViewById(R.id.verificationCode);
        EditText firstNameView = findViewById(R.id.firstName);
        EditText lastNameView = findViewById(R.id.lastName);
        EditText emailView = findViewById(R.id.email);
        EditText usernameView = findViewById(R.id.username);
        EditText passwordView = findViewById(R.id.password);
        String verificationCode = verificationCodeView.getText().toString().trim();
        String firstName = firstNameView.getText().toString().trim();
        String lastName = lastNameView.getText().toString().trim();
        String email = emailView.getText().toString().trim();
        String username = usernameView.getText().toString().trim();
        String password = passwordView.getText().toString().trim();
        if (firstName.length() == 0 || lastName.length() == 0 || email.length() == 0 || username.length() == 0 || password.length() == 0) {
            Toast.makeText(getApplicationContext(), "Something is wrong. Please check your inputs.", Toast.LENGTH_LONG).show();
        } else {
            JSONObject registrationForm = new JSONObject();
            try {
                registrationForm.put("subject", "verify");
                registrationForm.put("verification_code", verificationCode);
                registrationForm.put("firstname", firstName);
                registrationForm.put("lastname", lastName);
                registrationForm.put("email", email);
                registrationForm.put("username", username);
                registrationForm.put("password", password);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), registrationForm.toString());
            verifyPost = true;
            postRequest(MainActivity.postUrl, body);
        }
    }
    public void postRequest(String postUrl, RequestBody postBody) {
        OkHttpClient client = new OkHttpClient();
        final Request request = new Request.Builder()
                .url(postUrl)
                .post(postBody)
                .header("Accept", "application/json")
                .header("Content-Type", "application/json")
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // Cancel the post on failure.
                call.cancel();
                Log.d("FAIL", e.getMessage());
                // In order to access the TextView inside the UI thread, the code is executed inside runOnUiThread()
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        TextView responseText = findViewById(R.id.responseText);
                        responseText.setText("Failed to Connect to Server. Please Try Again.");
                    }
                });
            }
            @Override
            public void onResponse(Call call, final Response response) {
                // In order to access the TextView inside the UI thread, the code is executed inside runOnUiThread()
                final TextView responseTextRegister = findViewById(R.id.responseTextRegister);
                try {
                    final String responseString = response.body().string().trim();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            EditText firstNameView = findViewById(R.id.firstName);
                            EditText lastNameView = findViewById(R.id.lastName);
                            EditText emailView = findViewById(R.id.email);
                            EditText usernameView = findViewById(R.id.username);
                            EditText passwordView = findViewById(R.id.password);
                            EditText verificationCode = findViewById(R.id.verificationCode);
                            Button verifyButton = findViewById(R.id.verifyButton);
                            Button registerButton = findViewById(R.id.registerButton);
                            if (registerPost == true) { // Response to a registration post
                                if (responseString.equals("success")) {
                                    Toast.makeText(getApplicationContext(), "Pending E-mail Verification", Toast.LENGTH_LONG).show();
                                    firstNameView.setEnabled(false);
                                    lastNameView.setEnabled(false);
                                    emailView.setEnabled(false);
                                    usernameView.setEnabled(false);
                                    passwordView.setEnabled(false);
                                    registerButton.setEnabled(false);
                                    verificationCode.setEnabled(true);
                                    verifyButton.setEnabled(true);
                                    Toast.makeText(registerActivityContext, "Registration is pending e-mail confirmation", Toast.LENGTH_LONG).show();
                                    responseTextRegister.setText("Registration is pending e-mail confirmation.nGo to your e-mail (check the spam folder), copy the conformation code, paste it down here, and click Confirm.nYou will not be registred if e-mail is not confirmed.");
                                } else if (responseString.equals("email")) {
                                    responseTextRegister.setText("E-mail is already registered. Please use another e-mail.");
                                } else if (responseString.equals("username")) {
                                    responseTextRegister.setText("Username already exists. Please chose another username.");
                                } else {
                                    responseTextRegister.setText("Something went wrong. Please try again later.");
                                }
                                registerPost = false;
                            } else if (verifyPost == true) { // Response to a verification post
                                if (responseString.equals("success")) {
                                    verificationCode.setEnabled(false);
                                    verifyButton.setEnabled(false);
                                    Toast.makeText(registerActivityContext, "Your e-mail is verified successfully", Toast.LENGTH_LONG).show();
                                    responseTextRegister.setText("Your e-mail is verified successfully and you are now a user. You can login.");
                                    Intent intent = new Intent();
                                    intent.putExtra("status", "Your e-mail is verified successfully and you are now a user. You can login.");
                                    setResult(1, intent);
                                    finish();//finishing activity and return to the calling activity.
                                } else if (responseString.equals("failure")) {
                                    Toast.makeText(registerActivityContext, "You can register again after validating your data", Toast.LENGTH_LONG).show();
                                    responseTextRegister.setText("Sorry. E-mail is not verified. Registration failed. You can register again after validating your data.");
                                } else {
                                    responseTextRegister.setText("Something went wrong. Please try again later.");
                                }
                                verifyPost = false;
                            }
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

Conclusion

This tutorial extended the registration and login system created in a previous tutorial so that the user can add an email address. To make sure the email address belongs to the user, a verification code is sent to the email address. Once the user has copied and pasted the verification code, they’ll be successfully registered in the system.

Fritz

Our team has been at the forefront of Artificial Intelligence and Machine Learning research for more than 15 years and we're using our collective intelligence to help others learn, understand and grow using these new technologies in ethical and sustainable ways.

Comments 0 Responses

Leave a Reply

Your email address will not be published. Required fields are marked *

wix banner square