Skip to content
login.html 8.32 KiB
Newer Older
<!DOCTYPE html>
<html>
    <head>
        {% for src in js %}
            <script type="text/javascript" src="{{ src }}"></script>
        {% endfor %}
        {% for src in css %}
            <link type="text/css" rel="stylesheet" href="{{ src }}">
        {% endfor %}
        
        <script type="text/javascript" src="{{ url_for( 'send_app_files', path = 'webauthn.js' ) }}"></script>
        <script type="text/javascript" src="{{ url_for( 'send_app_files', path = 'functions.js' ) }}"></script>
        <link type="text/css" rel="stylesheet" href="{{ url_for( 'send_app_files', path = 'app.css' ) }}">
        
        <script type="text/javascript">
            baseurl = "{{ baseurl }}";
        </script>
    </head>
    <body>
Marco De Donno's avatar
Marco De Donno committed
        <div class="icnml_central">
            <h1 style="margin-bottom: 0px">ICNML</h1>
            <h4 style="margin-top: 0px">International Close Non-Matches Library</h4>
            
Marco De Donno's avatar
Marco De Donno committed
            <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 icnml_box_content">
                <div id="icnml_box_fields" class="icnml_box_fields">
Marco De Donno's avatar
Marco De Donno committed
                	<div style="text-align: right;">
                		<label for="username">Username</label>
                	</div>
                	<div>
                		<input id="username" name="username" type="text" />
                    </div>
Marco De Donno's avatar
Marco De Donno committed
                	<div style="text-align: right;">
                		<label for="password">Password</label>
                	</div>
                	<div>
                		<input id="password" name="password" type="password" />
                    </div>
                </div>
Marco De Donno's avatar
Marco De Donno committed
                <div id="icnml_login_error" class="icnml_box_error"></div>
                <div id="warning" class="icnml_box_warning"></div>
                <div class="icnml_button">
Marco De Donno's avatar
Marco De Donno committed
                	<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>
Marco De Donno's avatar
Marco De Donno committed
                <div class="icnml_shybox" id="password_reset">
                    <a href="{{ url_for( 'password_reset' ) }}">Forgotten password ?</a>
                    <br>
                    <a href="{{ url_for( 'new_user' ) }}">Sign-in</a>
Marco De Donno's avatar
Marco De Donno committed
            </div>
            <div class="icnml_shybox" id="icnml_version"></div>
        </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();
Marco De Donno's avatar
Marco De Donno committed
    		
        	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 );
            
            var e = encrypt( password_local, "{{ session_security_key }}" );
            sessionStorage.setItem( "session_key", e );
            
        	$.ajax( {
	            url: "{{ url_for( 'do_login' ) }}",
	            dataType: "json",
	            method: "POST",
	            data: {
Marco De Donno's avatar
Marco De Donno committed
	            	username: username,
	            	password: password
	            },
	            success: function( data )
	            {
	                if( ! data.error )
	                {
	                	if( data.logged )
                		{
                			location.href = "{{ url_for( 'home' ) }}";
Marco De Donno's avatar
Marco De Donno committed
                		
                		} else if( data.next_step === "totp" ) {
Marco De Donno's avatar
Marco De Donno committed
                			build_totp_form();
            			
                		} else if( data.next_step === "securitykey" ) {
                			build_securitykey_form();
            			
                		} else {
                			if( typeof data.message !== "undefined" )
                				var message = "Invalid username/password";
                			$( "#icnml_login_error" ).text( message );
Marco De Donno's avatar
Marco De Donno committed
	                	
	                	$( "#login_button > span" ).text( "Login" );
Marco De Donno's avatar
Marco De Donno committed
    	var login_action_totp = function()
		{
    		$( "#icnml_login_error" ).html( "" );
    		$( "#login_button > span" ).text( "Please wait..." );
Marco De Donno's avatar
Marco De Donno committed
    		
        	$.ajax( {
	            url: "{{ url_for( 'do_login' ) }}",
	            dataType: "json",
	            method: "POST",
Marco De Donno's avatar
Marco De Donno committed
	            data: {
	            	totp: $( "#totp" ).val()
Marco De Donno's avatar
Marco De Donno committed
	            },
	            success: function( data )
	            {
	                if( ! data.error )
	                {
	                	if( data.logged )
                		{
	                		location.href = "{{ url_for( 'home' ) }}";
                		} else if( data.next_step === "securitykey" ) {
                			build_securitykey_form();
            			
Marco De Donno's avatar
Marco De Donno committed
                		} else {
                			if( typeof data.message !== "undefined" )
                				$( "#icnml_login_error" ).text( data.message );
Marco De Donno's avatar
Marco De Donno committed
                		}
	                }
	            }
	        } );
		}
    	
    	var build_totp_form = function()
    	{
    		$( "#icnml_login_error" ).html( "" );
    		$( "#icnml_box_fields" ).html( "" );
			$( "#icnml_box_fields" )
Marco De Donno's avatar
Marco De Donno committed
				.append(
					$( "<div />" )
Marco De Donno's avatar
Marco De Donno committed
						.text( "TOTP" )
						.css( "text-align", "right" )
				)
				.append(
					$( "<div />" ).append(
						$( "<input />" )
Marco De Donno's avatar
Marco De Donno committed
							.attr( "id", "totp" )
							.attr( "name", "totp" )
							.on( "keyup", function( event )
Marco De Donno's avatar
Marco De Donno committed
                    		{
                            	if( event.keyCode == 13 )
                            	{
                            		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_reset" ).remove();
    		$( "#icnml_homepage_form" )
    				$( "<div />" )
    					.css( "margin-bottom", "10px" )
    					.text( "Logging with your security key..." )
    			);
    		
    		login_key();
Marco De Donno's avatar
Marco De Donno committed
    	/* Events binding */
		$( "#username" ).on( "keyup", function( event )
		{
        	if( event.keyCode == 13 )
        	{
        		event.preventDefault();
Marco De Donno's avatar
Marco De Donno committed
        		login_action_password();
        $( "#password" ).on( "keyup", function( event )
		{
        	if( event.keyCode == 13 )
        	{
        		event.preventDefault();
Marco De Donno's avatar
Marco De Donno committed
        		login_action_password();
        $( "#login_button" ).on( "click", login_action_password );
Marco De Donno's avatar
Marco De Donno committed
        
		$( "#username" ).focus();
		
        $( document ).ready( function()
        {
            if( !window.crypto || !window.crypto.subtle || !window.TextEncoder || !window.TextDecoder)
            {
                $( "#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();
        
        setTimeout( function()
		{
        	location.reload();
		}, {{ session_timeout }} * 1000 );
        
        /* Get the version of ICNML */
        $.ajax( {
            url: "{{ url_for( 'version' ) }}",
            dataType: "json",
            method: "GET",
            success: function( data ){
            	$( "#icnml_version" ).text( "ICNML version: " + data.version );
            }
        } );
    </script>
</html>
Marco De Donno's avatar
Marco De Donno committed