Search code examples
javascriptiosswiftmongodbrealm

How to change a user's password in Realm data base. iOS App


Hello everyone who are going to read this.

I’m developing an iOS app that has a registration feature based on the MongoDB’s Realm. Unfortunately they aren’t providing any examples how to handle email confirmation for registration user or changing password. At the moment I'm trying to come up with a way to provide a 'forgot password?' feature.

app.emailPasswordAuth.sendResetPasswordEmail(email: email)

After calling the code above user will receive a message on provided email. Message contain a link that will be handled by the script I added to the MongoDB Realm app on my RealmUI environment. I put there this script(Some part of this was found on the MongoDB forum, thank you guys).

<head>
<script src="https://unpkg.com/realm-web/dist/bundle.iife.js"></script>
<script>
const APP_ID = "app_id";
const app = new Realm.App({ id: APP_ID});
//Grab Tokens
const params = new URLSearchParams(window.location.search);
const token = params.get('token');
const tokenId = params.get('tokenId');

//Confirm client
app.emailPasswordAuth
.callResetPasswordFunction('[email protected]', 'SomethingButNotPassword123', [])
        .then(
    (value) => {
        console.log('SUCCESS');
        displayResult('SUCCESS');
    },
    (error) => {
        console.log(error);
        displayResult('error', err);
    }
);

 app.emailPasswordAuth
 .resetPassword(token, tokenId, 'newPassWord321')
 .then(() => displayResult('success'))
 .catch(err => displayResult('error', err))

//Display Message depending on result
function displayResult(result, err) {
    const message = document.getElementById("message");
    if (result === "success") {
        message.innerText = "Now you can reset your password";
    }
   else if (result === "error") {
       message.innerText = "Unable to change the password for this user. Please try again or contact our support team." + err;
   }
}
</script>

<title>E-mail Confirmation</title>
<style>
    h1 {text-align: center;}
    h3 {text-align: center;}
    h5 {text-align: center; background-color: whitesmoke;}
    p {text-align: center;}
    div {text-align: center;}
</style>
</head>
<body>
    <h1>App name</h1>
    <h3>Thanks for choosing our app!</h1>
    <h5 id = "message"></h5>
</body>
</html>

And this code actually works, it really does change the password for the given email, however It doesn’t fit my needs, because it changes a password for predefined email(new password defined in code as well). I want a user, after confirming that they own email, which was sent from iOS client. Go either to the page on the web with two textfields that are used for filling them with a new version of password, or going direct to the app and type there. I guess universal links could help me to achieve this kind of bahavior(I mean open either web site with textfields or open my app, depends on whether app was installed on the iPhone). I assume that I can put second part of this script to the web somehow and put there those textfields I mentioned above. After user filling them and press button, script executes .resetPasword method. But!

How can I understand on which email latter was sent by the iOS client from this script? I mean I need to know email from which the link(.sendResetPasswordEmail(email: email) method had sent) was opened

Is this real to perform, or maybe you know another way to handle reset-password feature for realm based application on iOS? Any response would be appreciated. Thank you.


Solution

  • Actually callResetPasswordFunction() was redundant, so I refactored(with a help from a friend of mine) my code a little bit and I'm going to post working solution for resetting password.

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <script src="https://unpkg.com/realm-web/dist/bundle.iife.js"></script>
    
    
        <title>Password resetting</title>
        <style>
            
            h5 { background-color: whitesmoke;}
            {
                text-align: center;
            }
           
        </style>
    </head>
    <body>
    <h1>App name</h1>
    <h3>Thanks for choosing our app!</h3>
    <h5 id = "message"></h5>
    
    <script>
        const APP_ID = "your app id";
        const app = new Realm.App({ id: APP_ID});
        //Grab Tokens
        const params = new URLSearchParams(window.location.search);
        const token = params.get("token");
        const tokenId = params.get("tokenId");
    
        if (!token || !tokenId) {
            alert('Token error')
        } else {
            saveNewPassword('desiredPassword', token, tokenId)
        }
    
    
        async function saveNewPassword(newPassword, token, tokenId) {
            console.log('token: ', token)
            console.log('tokenId: ', tokenId)
            console.log('new password: ', newPassword)
    
            try {
                await app.emailPasswordAuth.resetPassword({
                    password: newPassword,
                    token,
                    tokenId,
                });
                console.log('Password has been changed')
                displayResult('success')
            } catch(err) {
                console.log('Save password error', err);
                displayResult('error')
            }
        }
    
        //Display Message depending on result
        function displayResult(result, err) {
            const message = document.getElementById("message");
            if (result === "success") {
                message.innerText = "The password has been changed";
            }
            else if (result === "error") {
                message.innerText = "error change password";
            }
        }
    
    </script>
    </body>
    </html>