<!DOCTYPE html>
<html lang="en">
    <head>
        <title>ICNML</title>
        <meta name="description" content="International Close Non-Matches Library">
        
        {% autoescape false %}
            {{ app_files }}
        {% endautoescape %}
        
        <script type="text/javascript">
            baseurl = "{{ baseurl }}";
            homeurl = "{{ url_for( 'base.home' ) }}";
            begin_activate_url = "{{ url_for( 'login.webauthn_begin_activate' ) }}";
            verify_url = "{{ url_for( 'login.webauthn_verify' ) }}";
            begin_assertion_url = "{{ url_for( 'login.webauthn_begin_assertion' ) }}";
            verify_assertion_url = "{{ url_for( 'login.webauthn_verify_assertion' ) }}";
            
            localStorage.setItem( "session_key", "" );
        </script>
    </head>
    <body>
        <div class="icnml_central">
            <h1 style="margin-bottom: 0px">ICNML</h1>
            <h4 style="margin-top: 0px">International Close Non-Matches Library</h4>
            
            <div class="ui-widget-header ui-corner-top icnml_box_top">Please enter your login information</div>
            <div id="icnml_homepage_form" class="ui-widget-content ui-corner-bottom" style="padding: 10px">
                <div id="icnml_box_fields" class="icnml_box_fields">
                    <div style="text-align: right;">
                        <label for="username">Username</label>
                    </div>
                    <div>
                        <input id="username" name="username" type="text" />
                    </div>
                    <div style="text-align: right;">
                        <label for="password">Password</label>
                    </div>
                    <div>
                        <input id="password" name="password" type="password" />
                    </div>
                </div>
                <div id="icnml_login_error" class="icnml_box_error"></div>
                <div id="icnml_login_warning" class="icnml_box_warning"></div>
                <div id="icnml_login_warning2" class="icnml_box_warning"></div>
                <div class="icnml_center">
                    <div class="icnml_button">
                        <a class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" id="login_button" role="button" aria-disabled="false">
                            <span class="ui-button-text">Login</span>
                        </a>
                    </div>
                </div>
                <div class="icnml_shybox" id="password_totp_reset">
                    <a href="{{ url_for( 'login.password_reset' ) }}">Password reset</a>
                </div>
                <div class="icnml_shybox" id="new_account">
                    <a href="{{ url_for( 'newuser.new_user' ) }}">Request an account</a>
                </div>
            </div>
            <div class="icnml_shybox" style="margin-top: 10px;">
                <span id="icnml_version"></span>
            </div>
            <div class="icnml_shybox">
                <a id="icnml_tree_files" href="#"></a>
            </div>
            <div class="icnml_shybox">
                <a id="icnml_documents" href="https://esc-md-git.unil.ch/ICNML/documents" style="text-decoration: underline">See the documents related to the ICNML project</a>
            </div>
            <script type="text/javascript">
                envtype = "{{ envtype }}";
                if( envtype !== "" )
                {
                    document.write( '<div class="ribbon-wrapper"><div class="ribbon">' + envtype + '</div></div>' );
                }
            </script>
        </div>
    </body>
    <script type="text/javascript">
        var login_action_password = async function()
        {
            $( "#icnml_login_error" ).html( "" );
            $( "#login_button > span" ).text( "Please wait..." );
            
            var username = $( "#username" ).val();
            var password = $( "#password" ).val();
            var password_local = $( "#password" ).val();
            
            password = await generateKey( password, "icnml_" + username, 20000 );
            password = password.substring( 0, 128 );
            password = "pbkdf2$sha512$icnml_" + username + "$20000$" + password;
            
            password_local = await generateKey( password_local, "icnml_" + username + "_localpassword", 50000 );
            password_local = password_local.substring( 0, 128 );
            localStorage.setItem( "session_key", password_local );
            
            $.ajax( {
                url: "{{ url_for( 'login.do_login' ) }}",
                dataType: "json",
                method: "POST",
                data: {
                    username: username,
                    password: password
                },
                success: function( data )
                {
                    if( ! data.error )
                    {
                        if( data.logged )
                        {
                            location.href = "{{ url_for( 'base.home' ) }}";
                        
                        } else if( data.next_step === "totp" ) {
                            build_totp_form();
                        
                        } else if( data.next_step === "securitykey" ) {
                            build_securitykey_form();
                        
                        } else if( data.next_step === "totp_reset" ) {
                            build_totp_reset_information();
                        
                        } else {
                            if( typeof data.message !== "undefined" )
                                var message = data.message;
                            else
                                var message = "Invalid username/password";
                            
                            $( "#icnml_login_error" ).text( message );
                            $( "#password" ).val( "" );
                            $( "#password" ).focus();
                        }
                        
                        $( "#login_button > span" ).text( "Login" );
                    }
                },
                error: function( data )
                {
                    $( "#icnml_login_error" ).text( "Network error" );
                }
            } );
        }
        
        var login_action_totp = function()
        {
            $( "#icnml_login_error" ).html( "" );
            $( "#login_button > span" ).text( "Please wait..." );
            
            var totp = $( "#totp" ).val();
            totp = totp.replace( /\D/g, '' );
            
            var save_serverside = $( "#totp_save_serverside" ).is( ":checked" );
            
            $.ajax( {
                url: "{{ url_for( 'login.do_login' ) }}",
                dataType: "json",
                method: "POST",
                data: {
                    totp: totp,
                    save: save_serverside
                },
                success: function( data )
                {
                    if( ! data.error )
                    {
                        if( data.logged )
                        {
                            location.href = "{{ url_for( 'base.home' ) }}";
                        
                        } else if( data.next_step === "securitykey" ) {
                            build_securitykey_form();
                        
                        } else {
                            if( typeof data.message !== "undefined" )
                                $( "#icnml_login_error" ).text( data.message );
                            
                            if( typeof data.time !== "undefined" )
                            {
                                $( "#login_button > span" )
                                    .text( "Login" );
                                
                                var server_time = moment.utc( data.time * 1000 )
                                    .local()
                                    .format( "MMMM Do YYYY, HH:mm:ss" );
                                
                                $( "#icnml_login_warning" )
                                    .text( "Current server time: " + server_time );
                                
                                if( typeof data.time_diff == "number" )
                                {
                                    var time_diff = data.time_diff;
                                    time_diff = Math.abs( time_diff );
                                    
                                    time_diff_h = Math.floor( time_diff / 3600 );
                                    time_diff_m = Math.floor( ( time_diff - time_diff_h * 3600 ) / 60 );
                                    
                                    var time_diff_msg = "Your phone time is probably off by "
                                    if( time_diff_h > 0 )
                                        time_diff_msg += time_diff_h + " hour(s) and "
                                    time_diff_msg += time_diff_m + " minute(s).";
                                    
                                    $( "#icnml_login_warning" )
                                        .css( "margin-bottom", "0px" );
                                    
                                    $( "#icnml_login_warning2" )
                                        .text( time_diff_msg );
                                }
                            }
                        }
                    }
                },
                error: function()
                {
                    $( "#icnml_login_error" ).text( "Network error" );
                    $( "#login_button > span" ).text( "Login" );
                }
            } );
        }
        
        var build_totp_form = function()
        {
            $( "#icnml_login_error" ).html( "" );
            $( "#icnml_box_fields" ).html( "" );
            
            $( "#password_totp_reset" ).html( "" );
            $( "#new_account" ).remove();
            
            $( "#icnml_box_fields" )
                .append(
                    $( "<div />" )
                        .text( "TOTP" )
                        .css( "text-align", "right" )
                )
                .append(
                    $( "<div />" ).append(
                        $( "<input />" )
                            .attr( "id", "totp" )
                            .attr( "name", "totp" )
                            .on( "keyup", function( event )
                            {
                                if( event.keyCode == 13 )
                                {
                                    event.preventDefault();
                                    login_action_totp();
                                }
                            } )
                    )
                )
                .append(
                    $( "<div />" )
                )
                .append(
                    $( "<div />" )
                        .css( "text-align", "right" )
                        .append(
                            $( "<span />" ).text( "Save the TOTP for 30 days" )
                        )
                        .append(
                            $( "<input />" )
                                .css( "text-align", "right" )
                                .attr( "type", "checkbox" )
                                .attr( "id", "totp_save_serverside" )
                        )
                );
            
            $( "#password_totp_reset" )
                .append(
                    $( "<a />" )
                        .attr( "href", "{{ url_for( 'login.totp_reset' ) }}" )
                        .text( "TOTP reset" )
                );
            
            $( "#login_button" ).off( "click" );
            $( "#login_button" ).on( "click", function( event )
            {
                event.preventDefault();
                login_action_totp();
            } );
            
            $( "#totp" ).focus();
        }
        
        var build_securitykey_form = function()
        {
            $( "#icnml_login_error" ).html( "" );
            $( "#icnml_box_fields" ).html( "" );
            
            $( "#icnml_box_fields" )
                .removeClass( "icnml_box_fields" )
                .addClass( "icnml_auto" );
            
            $( "#login_button" ).remove();
            $( "#password_totp_reset" ).remove();
            $( "#new_account" ).remove();
            
            $( "#icnml_homepage_form" )
                .prepend(
                    $( "<div />" )
                        .css( "margin-bottom", "10px" )
                        .text( "Logging with your security key..." )
                );
            
            login_key();
        }
        
        var build_totp_reset_information = function()
        {
            $( "#icnml_login_error" ).html( "" );
            $( "#icnml_box_fields" ).html( "" );
            
            $( "#icnml_box_fields" )
                .removeClass( "icnml_box_fields" )
                .addClass( "icnml_auto" );
            
            $( "#login_button" ).remove();
            $( "#password_totp_reset" ).remove();
            $( "#new_account" ).remove();
            
            $( "#icnml_homepage_form" )
                .prepend(
                    $( "<div />" )
                        .css( "text-align", "center" )
                        .html( "Your second factor is not configured at the moment.<br>Click on the link bellow to reset it.<br>" )
                        .append( $( "<a />" )
                            .attr( "href", "{{ url_for( 'login.totp_reset' ) }}" )
                            .text( "TOTP reset" )
                        )
                );
        }
        
        /* Events binding */
        $( "#username" ).on( "keyup", function( event )
        {
            if( event.keyCode == 13 )
            {
                event.preventDefault();
                $( "#password" ).focus();
            }
        } );
        $( "#password" ).on( "keyup", function( event )
        {
            if( event.keyCode == 13 )
            {
                event.preventDefault();
                login_action_password();
            }
        } );
        
        $( "#login_button" ).on( "click", login_action_password );
        
        $( "#username" ).focus();
        
        $( document ).ready( function()
        {
            if( !window.crypto || !window.crypto.subtle || !window.TextEncoder || !window.TextDecoder)
            {
                $( "#icnml_login_warning" )
                    .text( "Your browser does not support client-side cryptography. Please use compatible browser (Firefox, Chrome, Opera, Safari, ...) to protect your password before sending it to the ICNML server." );
                
                $( "#username" ).prop( "disabled", true );
                $( "#password" ).prop( "disabled", true );
                $( "#login_button" ).remove();
            }
        } );
        
        /* Get the version of ICNML */
        $.ajax( {
            url: "{{ url_for( 'adm.route_version' ) }}",
            dataType: "json",
            method: "GET",
            success: function( data ){
                $( "#icnml_version" )
                    .text( "ICNML version: " + data.version );
                
                $( "#icnml_tree_files" )
                    .attr( "href", data.treeurl )
                    .attr( "target", "_blank" )
                    .css( "text-decoration", "underline" )
                    .text( "See and download the source code here" );
            }
        } );
    </script>
</html>

