Open In App

Create a Password Manager using React-Native

Last Updated : 11 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

This article will demonstrate how to create a Password Manager Application using React-Native. To assist users in securely storing and managing their passwords, we will develop a Password Manager mobile­ application using React Native for this project. The application will provide functionalities such as adding, viewing, copying, and de­leting stored passwords.

Let’s take a look at how our completed project will look:

Create-a-Password-Manager-using-React-Native

Prerequisites

Steps to Create React Native Application

Step 1: Create a React Native Application

Create a new React Native project for JokesGeneratorApp.

npx create-expo-app PasswordManagerApp

Step 2: ​Change the directory to the project folder:

cd PasswordManagerApp

Project Structure

Package.json

{
    "dependencies": {
        "react-native-paper": "4.9.2",
        "@expo/vector-icons": "^13.0.0",
        "react-native-vector-icons/FontAwesome": "*",
        "react-native-vector-icons": "10.0.0"
    }
}

Approach

This React Native app serves as a password manager. It allows users to add, edit, copy, and delete passwords for various websites. The app maintains a list of passwords, each containing website details, usernames, and masked passwords. Users can copy website names, usernames, and masked passwords to the clipboard for easy access. The app provides an editing feature, initiated by tapping the “Edit” button, enabling users to modify existing passwords.

Example: This example demonstrate a basic password manager where

  • The function “maskPassword” re­ceives a password string as input and returns the­ same password masked with asterisks.
  • This copyText function enable­s users to effortlessly copy te­xt, such as website URLs, username­s, and passwords, to their clipboard. Additionally, it sets a temporary ale­rt message called “ale­rtVisible” to notify users that the te­xt has been successfully copie­d.
  • The de­letePassword function allows users to re­move a password entry. It filters the­ passwords array, eliminating the specifie­d password and providing a success message.
  • The e­ditPassword function is invoked when the use­r intends to modify an existing password entry. It activate­s the editing flag, conseque­ntly altering the behavior of the­ “Save Password” button. 
  • The re­nderPasswordList function generate­s a list of password entries based on the­ data in the passwords array. It then maps each password e­ntry to a View, which includes details such as we­bsite, username, and a copy button.

Javascript




import React, { useState, useEffect } from "react";
import {
    View,
    Text,
    TextInput,
    TouchableOpacity,
    ScrollView,
    StyleSheet,
    Clipboard,
} from "react-native";
import Icon from "react-native-vector-icons/FontAwesome";
import { styles } from "./styles";
  
const App = () => {
    const [website, setWebsite] = useState("");
    const [username, setUsername] = useState("");
    const [password, setPassword] = useState("");
    const [passwords, setPasswords] = useState([]);
    const [alertVisible, setAlertVisible] = useState(false);
    const [editing, setEditing] = useState(false);
    const [editIndex, setEditIndex] = useState(null);
  
    useEffect(() => {
        showPasswords();
    }, []);
  
    const maskPassword = (pass) => {
        let str = "";
        for (let index = 0; index < pass.length; index++) {
            str += "*";
        }
        return str;
    };
  
    const copyText = async (txt) => {
        try {
            await Clipboard.setString(txt);
            setAlertVisible(true);
            setTimeout(() => {
                setAlertVisible(false);
            }, 2000);
        } catch (error) {
            console.error("Error copying text:", error);
        }
    };
  
    const deletePassword = (website) => {
        const updatedPasswords = passwords.filter(
            (e) => e.website !== website
        );
        setPasswords(updatedPasswords);
        alert(`Successfully deleted ${website}'s password`);
    };
  
    const showPasswords = () => {
        setPasswords([]);
        setWebsite("");
        setUsername("");
        setPassword("");
        setEditing(false);
        setEditIndex(null);
    };
  
    const savePassword = () => {
      
        // Check if any of the input fields is empty
        if (!website || !username || !password) {
            alert("Please fill in all fields.");
            return;
        }
  
        if (editing && editIndex !== null) {
            const updatedPasswords = [...passwords];
            updatedPasswords[editIndex] = {
                website,
                username,
                password,
            };
            setPasswords(updatedPasswords);
            setEditing(false);
            setEditIndex(null);
        } else {
            const newPassword = {
                website,
                username,
                password,
            };
            setPasswords([...passwords, newPassword]);
        }
        setWebsite("");
        setUsername("");
        setPassword("");
    };
  
    const editPassword = (index) => {
        setEditing(true);
        setEditIndex(index);
        setWebsite(passwords[index].website);
        setUsername(passwords[index].username);
        setPassword(passwords[index].password);
    };
  
    const renderPasswordList = () => {
        return passwords.map((item, index) => (
            <View style={styles.passwordItem} key={index}>
                <View style={styles.listItem}>
                    <Text style={styles.listLabel}>
                        Website:
                    </Text>
                    <Text style={styles.listValue}>
                        {item.website}
                    </Text>
                    <TouchableOpacity
                        style={styles.copyIcon}
                        onPress={() =>
                            copyText(item.website)
                        }>
                          
                        <Icon
                            name="copy"
                            size={20}
                            color="#555"/>
                              
                    </TouchableOpacity>
                </View>
  
                <View style={styles.listItem}>
                    <Text style={styles.listLabel}>
                        Username:
                    </Text>
                    <Text style={styles.listValue}>
                        {item.username}
                    </Text>
                    <TouchableOpacity
                        style={styles.copyIcon}
                        onPress={() =>
                            copyText(item.username)
                        }>
                          
                        <Icon
                            name="copy"
                            size={20}
                            color="#555"/>
                              
                    </TouchableOpacity>
                </View>
  
                <View style={styles.listItem}>
                    <Text style={styles.listLabel}>
                        Password:
                    </Text>
                    <Text style={styles.listValue}>
                        {maskPassword(item.password)}
                    </Text>
                    <TouchableOpacity
                        style={styles.copyIcon}
                        onPress={() =>
                            copyText(item.password)
                        }>
                          
                        <Icon
                            name="copy"
                            size={20}
                            color="#555"/>
                              
                    </TouchableOpacity>
                </View>
                <View style={styles.buttonsContainer}>
                    <TouchableOpacity
                        style={styles.editButton}
                        onPress={() => editPassword(index)}>
                          
                        <Icon
                            name="edit"
                            size={20}
                            color="#fff"/>
                              
                    </TouchableOpacity>
                    <TouchableOpacity
                        style={styles.deleteButton}
                        onPress={() =>
                            deletePassword(item.website)}>
                          
                        <Icon
                            name="trash"
                            size={20}
                            color="white"/>
                              
                    </TouchableOpacity>
                </View>
            </View>
        ));
    };
  
    return (
        <ScrollView style={styles.container}>
            <View style={styles.content}>
                <Text style={styles.heading}>
                    Password Manager
                </Text>
                <Text style={styles.subHeading}>
                    Your Passwords
                    {alertVisible && (
                        <Text id="alert"> (Copied!)</Text>
                    )}
                </Text>
                {passwords.length === 0 ? (
                    <Text style={styles.noData}>
                        No Data To Show
                    </Text>
                ) : (
                    <ScrollView horizontal>
                        <View style={styles.table}>
                            {renderPasswordList()}
                        </View>
                    </ScrollView>
                )}
  
                <Text style={styles.subHeading}>
                    {editing
                        ? "Edit Password"
                        : "Add a Password"}
                </Text>
                <TextInput
                    style={styles.input}
                    placeholder="Website"
                    value={website}
                    onChangeText={(text) =>
                        setWebsite(text)
                    }/>
                      
                <TextInput
                    style={styles.input}
                    placeholder="Username"
                    value={username}
                    onChangeText={(text) =>
                        setUsername(text)}/>
                          
                      
                <TextInput
                    style={styles.input}
                    placeholder="Password"
                    secureTextEntry={true}
                    value={password}
                    onChangeText={(text) =>
                        setPassword(text)
                    }/>
                      
                <TouchableOpacity
                    style={styles.submitButton}
                    onPress={savePassword}>
                      
                    <Text style={styles.submitButtonText}>
                        {editing
                            ? "Update Password"
                            : "Add Password"}
                    </Text>
                </TouchableOpacity>
            </View>
        </ScrollView>
    );
};
  
export default App;


Javascript




// styles.js
  
import { StyleSheet } from "react-native";
  
const styles = StyleSheet.create({
    container: {
        flex: 1,
        margin: 20,
    },
    content: {
        margin: 15,
    },
    heading: {
        fontSize: 30,
        fontWeight: "bold",
        marginBottom: 15,
        textAlign: "center",
        color: "#333",
    },
    subHeading: {
        fontSize: 23,
        fontWeight: "bold",
        marginBottom: 10,
        color: "#333",
    },
    noData: {
        fontSize: 17,
        fontStyle: "italic",
        marginBottom: 20,
        color: "#666",
    },
    table: {
        flexDirection: "row",
        backgroundColor: "white",
        borderRadius: 15,
        elevation: 4,
        marginBottom: 20,
        shadowColor: "grey",
        shadowOffset: { width: 0, height: 0 },
        shadowRadius: 5,
        shadowOpacity: 1,
    },
    passwordItem: {
        flexDirection: "column",
        alignItems: "center",
        borderBottomWidth: 1,
        borderBottomColor: "#ddd",
        padding: 15,
    },
    listItem: {
        flexDirection: "row",
        justifyContent: "space-between",
        alignItems: "center",
        marginRight: 10,
        marginBottom: 10,
    },
    listLabel: {
        fontWeight: "bold",
        marginBottom: 5,
        color: "#333",
        fontSize: 19,
    },
    listValue: {
        flex: 1,
        fontSize: 18,
        color: "#444",
        paddingLeft: 10,
    },
    copyIcon: {
        marginRight: 10,
        paddingLeft: 10,
    },
    deleteButton: {
        backgroundColor: "red",
        borderRadius: 4,
        padding: 5,
        marginLeft: 10,
    },
    editButton: {
        backgroundColor: "blue",
        borderRadius: 4,
        padding: 5,
        marginRight: 10,
    },
    buttonsContainer: {
        flexDirection: "row",
    },
    input: {
        borderWidth: 2,
        borderColor: "#eee",
        paddingVertical: 10,
        paddingHorizontal: 15,
        marginBottom: 20,
        fontSize: 16,
        borderRadius: 10,
        backgroundColor: "white",
        shadowColor: "grey",
        shadowOffset: { width: 0, height: 0 },
        shadowRadius: 10,
        shadowOpacity: 1,
        elevation: 4,
    },
    submitButton: {
        backgroundColor: "green",
        color: "white",
        fontWeight: "bold",
        borderRadius: 10,
        paddingVertical: 15,
        paddingHorizontal: 30,
        shadowColor: "black",
        shadowOffset: { width: 2, height: 2 },
        shadowRadius: 15,
        shadowOpacity: 1,
        elevation: 4,
    },
    submitButtonText: {
        color: "white",
        textAlign: "center",
        fontSize: 18,
    },
});
export { styles };


Steps to Run

To run react native application use the following command:

npx expo start
  • To run on Android:
npx react-native run-android
  • To run on iOS:
npx react-native run-ios

Output:

Create-a-Password-Manager-using-React-Native



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads