Skip to content

Companies Guide

This companies guide assumes that you have already completed the TheM>Getting Started>Quick Start guide and are familiar with TheM class, TheM submodule initialization, and creating/listening for custom events. This guide also assumes that you have already installed the amplifi_mobile_sdk package into your project and placed the following minified libraries in the /lib folder of your project: axios.min.js (Optional - fetch will be used if axios is not present), crypto-js.min.js, lz-string.min.js, moment.min.js, and socket.io.min.js. In addition, you should have completed the Onboarding Company Guide tutorial in order to create and onboard a business user which can be logged into your ampliFi instance.

1. In the src folder of your project (from the Quick Start guide of the TheM Getting Started section), create a new file called companies.js with the following code.

companies.js

import ClassTheM from "../node_modules/@PayGearsCorp/amplifi_mobile_sdk/TheM/them.mjs";

import { thisDevice } from "./android-demo-device.js"; //android device emulator for testing

const AMPLIFI_BASE_URL = "PUT_YOUR_INSTANCE_URL_HERE"; //Speak to a support representative to be issued a sandbox instance URL
const AMPLIFI_CORE_URL = `${AMPLIFI_BASE_URL}core/`;
const DEVICE_TAG = "PUT_YOUR_DEVICE_TAG_HERE"; //Use deviceTag obtained from onboarding company tutorial for this device

/*
For this tutorial, you will need a previously created company user with the currently logged in user designated as an admin role in the company.
*/

const subClassesToInit = [
    //"accounts",
    //"attachments",
    //"beneficiaries",
    //"cards",
    //"cheques",
    "common",
    "companies",
    //"externalAccounts",
    //"fdrs",
    //"fundstransfer",
    //"fxrates",
    "genericRequests",
    //"ious",
    //"onboarding",
    //"payees",
    //"remittance",
    //"restrictions",
    //"statics",
    "user"
];


export const companiesTutorial = async (subClasses = "") => {
    TheM = new ClassTheM({
        config: {
            AFiInstanceId: "test",
            modulesFolder: "",
            modulesFolderOnboarding: "",
            webworkerFolder: "../TheM/",
            baseLibURL: "../demo/lib/",
            backEndURL: AMPLIFI_CORE_URL,
            socketURL: AMPLIFI_BASE_URL,
        },
        libs: {
        }
    });

    //Emulate user device before initializing TheM submodules
    TheM.thisDevice = {
        ...thisDevice,
        TheM,
        deviceTag: DEVICE_TAG,
    };

    //Initialize desired submodules
    //Some modules depend on others so must be initialized together
    //For instance, most submodules require the "common" subclass to be initialized
    await TheM.doInit(subClasses);

    //companies workflow to try
    //Uncomment sections to demo TheM.companies actions or follow the instructions in the browser

    //Prepare for logging in
    //Log in using the instructions in the browser or use the doAuthenticate method from the device emulator we created during onboarding
    await TheM.thisDevice.doAuthenticate(DEVICE_TAG);

    //Check if the companies submodule is ready and set if necessary
    if (!TheM.companies.isReady) {
        TheM.companies.isReady = true;
    };

    //Check if the genericRequests submodule is ready and set if necessary
    if (!TheM.genericRequests.isReady) {
        TheM.genericRequests.isReady = true;
    };

    //Pull fresh data from the server if necessary
    await TheM.companies.doUpdate();
    await TheM.genericRequests.doUpdate();

    /*
    //INVITE A USER TO THE COMPANY
    //If the currently logged in user is an admin in the company, then they can invite/manage other users
    if (TheM.companies[0] && TheM.companies[0].isAdmin) {
        await TheM.companies[0].doInviteUser({
            firstName: "John",
            lastName: "Doe",
            address: {
                addressLine1: "456 Main Str.",
                addressLine2: "Apt. 10",
                city: "Harrisburg",
                state: "PA",
                postalCode: "12345",
                countryCode: "US",
                country: "US"
            },
            mobile: "5556668888",
            email: "johndoe.test@email.test" //must be unique compared to other users in this Company
        });
    } else {
        throw "The current user is not an admin of the company.";
    }
    */

    const user = TheM.companies[0].users.length > 1 && TheM.companies[0].users[1].AFiUserId != TheM.user.AFiUserId ? TheM.companies[0].users[1] : undefined;
    if (!user) {
        throw "Only the currently logged in user exists in this Company. Uncomment the INVITE A USER TO THE COMPANY section to invite a new user before trying to suspend or delete a user.";
    }

    /*
    //MODIFY A USER'S ROLE
    await TheM.companies[0].doModifyUser({
        AFiUserId: user.AFiUserId,
        role: "user", //or "admin"
        isDeleted: false //or true
    });

    //SUSPEND/UN-SUSPEND A COMPANY USER
    if (user) {
        await TheM.companies[0].doSuspendUser({
            AFiUserId: user.AFiUserId,
            isSuspended: true //or false
        });
    } else {
        throw "Attempt to suspend self!"
    }
    */

    /*
    //DELETE A USER FROM THE COMPANY
    if (user) {
        await TheM.companies[0].doDeleteUser({
            AFiUserId: user.AFiUserId
        });
    } else {
        throw "Attempt to delete self from company!"
    }
    */

    //Update TheM.companies to reflect any changes that have occurred on the server
    await TheM.companies.doUpdate(true);
    console.log(`TheM.companies[0].users: ${JSON.stringify(TheM.companies[0].users)}`)

    //Logout when finished
    //await TheM.user.doLogout();

};

await companiesTutorial(subClassesToInit.join(" "));

2. The companies module expects the user to be using some type of device so make sure the android-demo-device.js file used during onboarding the company is still in your /src folder.

3. Create a new file in the /demo folder of your project called companies.html with the following code.

companies.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />

    <title>ampliFi</title>

    <script>
        var TheM;
        var TheM_config;
    </script>

    <script src="../lib/socket.io.min.js"></script>
    <script src="../lib/lz-string.min.js"></script>
    <script src="../lib/moment.min.js"></script>
    <script src="../lib/axios.min.js"></script>
    <script src="../lib/crypto-js.min.js"></script>
    <script type="module" src="/../src/companies.js"></script>

    <style>
        html {
            color: white;
            background-color: black;
        }
    </style>
</head>


<body>
    <div>
        Hit F12 to open the browser console.
        Start working with TheM by typing "TheM" into the browser console.
    </div>
    <br />
    <br />
    <div>
        1. In order to log a user in, we will need to prepare the user credentials using the encryptedServerSecret
        stored locally during onboarding the company. Type the following to retrieve the encryptedServerSecret. (Or skip
        steps 1-5
        by using the doAuthenticate method in the device emulator like so, `await
        TheM.thisDevice.doAuthenticate(DEVICE_TAG);`.)
        <br /><br />
        <code>let { encryptedServerSecret } = await TheM.thisDevice.retrieveLocally("encryptedServerSecret", true);</code>
        <br /><br />
        Type <code>encryptedServerSecret</code> into the browser console and hit enter to view the encryptedServerSecret
        value.
        <br /><br />
        2. Since we are using an emulated android device to log in, we need to get the cryptotext value like so.
        <br /><br />
        <code>
            let _SUPER_SECRET = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";<br />
            let _dtsValueString = (new Date()).valueOf().toString();<br />
            let serverSecret = CryptoJS.AES.decrypt(encryptedServerSecret, _SUPER_SECRET).toString(CryptoJS.enc.Utf8);<br />
            let cryptotext = CryptoJS.AES.encrypt((TheM.thisDevice.deviceTag) + _dtsValueString, serverSecret).toString(); 
        </code>
        <br /><br />
        3. Set a socket connection for bidirectional communication.
        <br /><br />
        <pre><code>TheM.thisDevice.halfRef = TheM.common.GetRandomSTR(40);<br />let manager = new TheM.io.Manager(TheM.config.socketURL + "?halfRef=" + TheM.thisDevice.halfRef, {<br />  autoConnect: false<br />});<br />let socket = manager.socket("/");</code></pre>
        <br />
        4. Open the socket connection.
        <br /><br />
        <pre><code>manager.connect(function (data) {<br />  console.log("established real-time comm channel for onboarding");<br />  TheM.thisDevice.isRealTimeCommAvailable = true;<br />});</code></pre>
        <br />
        5. Log the user in using the deviceTag obtained during onboarding and the newly created cryptotext.
        <br /><br />
        <pre><code>const credentials = {<br />  "dtsValueString": _dtsValueString,<br />  "deviceTag": "PUT_DEVICE_TAG_HERE",<br />  "deviceData": TheM.thisDevice.data,<br />  "channel": TheM.thisDevice.platform,<br />  "dynamicScreensVersion": TheM.thisDevice.dynamicScreensVersion,<br />  "socket": {<br />    halfRef: TheM.thisDevice.halfRef<br />  },<br />  "pushMessToken": TheM.thisDevice.pushMessToken,<br />  "cryptotext": cryptotext<br />};<br />await TheM.user.doLogin(credentials);</code></pre>
        <br />
        6. After authentication, check if the companies and generic requests submodules are ready and set if necessary.
        <br /><br />
        <code>
            console.log(`TheM.companies.isReady: ${TheM.companies.isReady}`);<br />
            console.log(`TheM.genericRequests.isReady: ${TheM.genericRequests.isReady}`);<br />
            TheM.companies.isReady = true;<br />
            TheM.genericRequests.isReady = true;
        </code>
        <br /><br />
        7. Pull fresh data from the server if necessary.
        <br />
        <pre><code>await TheM.companies.doUpdate();<br />await TheM.genericRequests.doUpdate();</code></pre>
        8. INVITE A USER TO THE COMPANY.
        <br />
        <pre><code>if (TheM.companies[0] && TheM.companies[0].isAdmin) {<br />  await TheM.companies[0].doInviteUser({<br />    firstName: "John",<br />    lastName: "Doe",<br />    address: {<br />      addressLine1: "456 Main Str.",<br />      addressLine2: "Apt. 10",<br />      city: "Harrisburg",<br />      state: "PA",<br />      postalCode: "12345",<br />      countryCode: "US",<br />      country: "US"<br />    },<br />    mobile: "5556668888",<br />    email: "johndoe.test@email.test" //must be unique compared to other users in this Company<br />  });<br />} else {<br />  throw "The current user is not an admin of the company.";<br />}</code></pre>
        9. Pull fresh data from the server if necessary after the invitation is sent out.
        <br />
        <pre><code>await TheM.companies.doUpdate(true);<br />TheM.companies[0].users;</code></pre>
        10. Before attempting to manage users, make sure a user other than the currently logged in user exists.
        <br />
        <pre><code>const user = TheM.companies[0].users.length > 1 && TheM.companies[0].users[1].AFiUserId != TheM.user.AFiUserId ? TheM.companies[0].users[1] : undefined;<br />if (!user) {<br />  throw "Only the currently logged in user exists in this Company. Please invite a user before attempting to manage other users.";<br />}</code></pre>
        11. MODIFY A USER'S ROLE.
        <br />
        <pre><code>await TheM.companies[0].doModifyUser({<br />  AFiUserId: user.AFiUserId,<br />  role: "user", //or "admin"<br />  isDeleted: false //or true<br />});</code></pre>
        12. SUSPEND/UN-SUSPEND A COMPANY USER.
        <br />
        <pre><code>if (user) {<br />  await TheM.companies[0].doSuspendUser({<br />    AFiUserId: user.AFiUserId,<br />    isSuspended: true //or false<br />  });<br />} else {<br />  throw "Attempt to suspend self!"<br />}</code></pre>
        13. Pull fresh data from the server if necessary after the the user is modified/suspended.
        <br />
        <pre><code>await TheM.companies.doUpdate(true);<br />TheM.companies[0].users;</code></pre>
        14. DELETE A USER FROM THE COMPANY.
        <br />
        <pre><code>if (user) {<br />  await TheM.companies[0].doDeleteUser({<br />    AFiUserId: user.AFiUserId<br />  });<br />} else {<br />  throw "Attempt to delete self from company!"<br />}</code></pre>
        15. Keep exploring TheM.companies properties and methods and log out when finished.
        <br /><br />
        <code>
            await TheM.user.doLogout();
        </code>
        <br /><br />
    </div>
</body>

</html>

4. Start a server in the root folder of your project.

py -m http.server 8000

5. Open a browser and enter the following URL: http://localhost:8000/demo/

6. Click on the link for "companies.html" and follow the instructions to log in, invite a new user to the company, modify/suspend/delete a user, and log out.