HR/CryptoSync

View on GitHub
static/setup.html

Summary

Maintainability
Test Coverage
<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>Crypto.Sync Setup</title>
    <link rel="stylesheet" href="style/setup.css" charset="utf-8">
    <!-- <script language="javascript" type="text/javascript" src="js/handle.js"></script> -->
</head>

<body>
    <section id="setup">
        <div class="panel-container">
            <div id="panel-default">
                <header>
                    <div class="banner banner-left">
                        <div class="marquee marquee-1">
                            Information is the resolution of uncertainty.&nbsp;
                        </div>
                        <div class="marquee marquee-1">
                            Rather be without a state than without a voice.&nbsp;
                        </div>
                        <div class="marquee marquee-1">
                            Freedom is never voluntarily given by oppressors.&nbsp;
                        </div>
                        <div class="marquee marquee-1">
                            Everyone has secrets to conceal; Privacy to protect.&nbsp;
                        </div>
                        <div class="marquee marquee-1">
                            Crypto is the ultimate form of non-violent direct action.&nbsp;
                        </div>
                    </div>
                    <div class="banner banner-right">
                        <div class="marquee marquee-2">
                            aNdtYE1jkAF8i8e6LgqAHNvS5J3Jc9H6XcUlM6YUIDi8rj3a0DLl
                        </div>
                        <div class="marquee marquee-2">
                            zLAgN6Umn61buZC8I6D6+mjZQW2Ap0eXJYDmAi/uGKUQ5ezHI0GI
                        </div>
                        <div class="marquee marquee-2">
                            3j6Nh1XO7WTRFa+1F3i38+TKvdhLt8kS8NAJkS5U670gElWDSffT
                        </div>
                        <div class="marquee marquee-2">
                            yUuJBEfzkIv6t4dcGXSoX4nOh4KFjhrdIymLpnpOlw+7VGLxqWHl
                        </div>
                        <div class="marquee marquee-2">
                            fG2w7C7LKU9eoB4hKjvWJ7EhXPBbzY/+/14VqjCG/O4Kqqr2sWGb
                        </div>
                    </div>
                    <img src="images/icons/CryptoSync.svg" alt="CryptoSync Logo" class="himg" />
                    <h1>Welcome to Crypto.Sync</h1>
                    <p>Crypto.Sync an end-to-end encryption cloud synchronisation client that simply manages the encryption of your cloud data for you.
                    </p>
          <p class="intrfo">This setup will walk you through setting up Crypto.Sync. Press the button below to get started.</p>
                </header>
                <button class="fancy navigationLink" onclick="navigate(this.getAttribute('data-target'))" data-target="accounts" id="getstarted">GET STARTED</button>
            </div>
            <div id="panel-accounts">
                <section class="accounts">
                    <header>
                        <div class="banner">
                            <img class="himg" src="images/icons/csp_accounts.svg" alt="" />
                        </div>
                        <h1>Add a Cloud Service Account</h1>
                    </header>
                    <div class="list">
                        <div class="item">
                            <a class="navigationLink csp" data-target="auth" data-auth="gdrive">
                                <img src="images/icons/gdrive.svg" />
                                <div class="name">Google Drive</div>
                                <img src="images/icons/foward.svg" alt="" class="icon right" />
                            </a>
                        </div>
                        <!-- <div class="item">
                            <a class="navigationLink csp" data-target="auth" data-auth="dropbox">
                                <img src="images/icons/dropbox.svg" />
                                <div class="name">Dropbox</div>
                                <img src="images/icons/foward.svg" alt="" class="icon right" />
                            </a>
                        </div> -->
                        <div class="item err">
                            <div class="name"></div>
                        </div>
                    </div>
                </section>
                <footer>
                    <a href="#" class="back navigationLink" data-target="default">
                        <img src="images/icons/back.svg" alt="" />
                    </a>
                </footer>
            </div>
            <div id="panel-auth">
                <header class="minimal">
                    <div class="banner">
                        <svg class="spinner" width="65px" height="65px" viewbox="0 0 66 66" xmlns="http://www.w3.org/2000/svg">
                            <circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle>
                        </svg>
                    </div>
                    <h1>Authorising...</h1>
                </header>
            </div>
            <div id="panel-masterpass">
                <section id="masterpassprompt">
                    <header>
                        <div class="banner">
                            <img class="himg" src="images/icons/CryptoSyncVault.svg" alt="" />
                        </div>
                        <h1>Set a MasterPass for the Vault</h1>
                        <img class="info" src="images/icons/info.svg" alt="" />
                        <p class="info">The Vault contains all the secret keys for your encrypted data is encrypted using a Master Password - your MasterPass.</p>
                    </header>
                    <form onsubmit="return false;">
                        <div class="masterpass">
                            <input type="password" name="name" id="name" class="" placeholder="********" />
                            <label for="password"></label>
                        </div>

                    </form>
                    <button class="fancy" id="setMasterPass">SET</button>
                    <p class="note">
                        NOTE: If lost, all previously synced data will be unrecoverable! So, please store it safely.
                    </p>
                </section>
                <footer>
                    <a href="#" class="back navigationLink" data-target="accounts">
                        <img src="images/icons/back.svg" alt="" />
                    </a>
                </footer>
            </div>
            <div id="panel-done">
                <header>
                    <div class="banner">
                        <img src="images/icons/done.svg" class="himg" />
                    </div>
                    <h1>All done!</h1>
                    <p>You have successfully setup Crypto.Sync. Please click finish and open the app again so that it can start doing its magic and protecting your privacy.</p>
                </header>
                <button class="fancy done navigationLink" id="done">FINISH</button>
                <footer class="credit">
                    <img src="images/icons/code.svg" alt="" class="icon" /> with
                    <img src="images/icons/heart.svg" alt="" class="icon" /> by <a onclick="event.preventDefault();require('shell').openExternal('https://git.io/HR');">Habib Rehman</a>
                </footer>
            </div>
        </div>
    </section>
    <script type="text/javascript">
    var remote = require('electron').remote,
        ipcRenderer = require('electron').ipcRenderer,
        webContents = remote.getCurrentWebContents(),
        rconsole = remote.getGlobal("console"),
        nav_to = getParam("nav_to", window.document.URL),
        authErr,
        errLabel;
    window.$ = window.jQuery = require('jquery');

    /* Network change event */
    function updateOnlineStatus() {
        ipcRenderer.send('online-status-changed', navigator.onLine ? 'online' : 'offline');
    };
    $(window).on('online', updateOnlineStatus);
    $(window).on('offline', updateOnlineStatus);
    updateOnlineStatus();

    /* Encryption animation */
    $(window).load(function() {
        $(document).keydown(function(e) {
            switch (e.which) {
                case 39: // right
                    navigate($("#panel-default button").first().data("target"));
                    break;
                case 37: // left
                    navigate($(".current .back").first().data("target"));
                    break;

                default:
                    return; // exit this handler for other keys
            }
            e.preventDefault(); // prevent the default action (scroll / move caret)
        });
        /* Variable assignments */
        authErr = $("div.item.err > div.name").first();
        errLabel = $('label[for="password"]').first();
        /* Navigation */
        authErr.hide();
        errLabel.hide();
        $(".navigationLink").each(function(index) {
            $(this).click(function() {
                if (this.hasAttribute("data-auth")) navigate(this.getAttribute("data-target"), this.getAttribute("data-auth"));
                navigate(this.getAttribute("data-target"));
            });
        });

        navigate((nav_to) ? nav_to : "default");

        /* setMasterPass */
        $("#setMasterPass").click(function() {
            console.log("setMasterPass button clicked");
            var MPregex = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$/g,
                MasterPass = $("input#name").val();
            if (MPregex.test(MasterPass)) {
                errLabel.hide();
                ipcRenderer.send("setMasterPass", MasterPass);
            } else if (!MasterPass) {
                errLabel.text("please enter a masterpass".toLocaleUpperCase());
                errLabel.show();
            } else {
                errLabel.text("must contain at least 1 Alphabet, 1 number and 1 special character".toLocaleUpperCase());
                errLabel.show();
            }
        });
        $("#done").click(function() {
            ipcRenderer.send("done");
        });

        /* Encryption animation */

        if (!nav_to) {
            var speed = 4500;
            var offseted = speed * 0.6;
            $('.marquee-1').marquee({
                direction: 'right',
                gap: 0,
                duplicated: true,
                duration: speed
            }).addClass("visible");

            $('.marquee-2').marquee({
                direction: 'right',
                gap: 0,
                duplicated: true,
                duration: speed,
                delayBeforeStart: offseted
            });

            setTimeout(function() {
                $('.marquee-2').addClass("visible");
            }, offseted);
            $(".marquee").css("position", "relative");
            $(".banner + .himg").css("margin-top", "-7.5rem");
        }
    });

    /* Helper functions */
    function navigate(panelID, authType) {
        var oldSel = $('.panel-container > div.current');
        var currSel = $("#panel-" + panelID);
        if (authType) {
            rconsole.log(`authType: ${authType}`);
            authErr.hide();
            initAuth(authType);
        }
        // TODO: find cleaner fix for unexpected button styling on panel transform
        $(".current button").hide();
        if (oldSel) oldSel.removeClass("current");
        $("#panel-" + panelID).addClass("current");
        $(".current button").show();
    }

    /* Authentication code retrieval */
    function getParam(name, url) {
        name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
        var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
            results = regex.exec(url);
        return (results === null) ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
    }

    function initAuth(authType) {
        // sendAuth event to main
        navigate("auth");
        ipcRenderer.send("initAuth", authType);
    }

    /* Event listeners */
    ipcRenderer.on("authResult", function(event, err) {
        rconsole.log(`IPCRENDER: authResult emitted`);
        // handle authResult
        if (!err) {
            // SUCCESS
            rconsole.log("IPCRENDER: No err. Navigating to masterpass...");
            navigate("masterpass");
        } else if (err === "access_denied") {
            rconsole.log("IPCRENDER: ERR, access_denied");
            authErr.text("Access to your account was denied. Please try again.").show();
            navigate("accounts");
        } else {
            rconsole.log(`IPCRENDER: unknown ERR, ${err}`);
            authErr.text(`Unknown error: ${err}`).show();
            navigate("accounts");
        }
    });
    ipcRenderer.on("setMasterPassResult", function(event, err) {
        rconsole.log("IPCRENDER: setMasterPassResult emitted");
        if (err) {
            errLabel.text(`ERROR: ${err}`.toLocaleUpperCase());
            errLabel.show();
        } else {
            navigate("done");
        }
    });

    </script>
    <script src="js/jquery.marquee.min.js" type="text/javascript"></script>
</body>

</html>