move migration, bugfixes, ....
This commit is contained in:
		
							parent
							
								
									5401e2594d
								
							
						
					
					
						commit
						18863bee7f
					
				
					 25 changed files with 255 additions and 33 deletions
				
			
		
							
								
								
									
										140
									
								
								lenticular_cloud/template/frontend/webauthn_register.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								lenticular_cloud/template/frontend/webauthn_register.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,140 @@
 | 
			
		|||
{#- This file is part of sner4 project governed by MIT license, see the LICENSE.txt file. -#}
 | 
			
		||||
{% extends 'frontend/base.html.j2' %}
 | 
			
		||||
 | 
			
		||||
{% block script %}
 | 
			
		||||
<script>
 | 
			
		||||
  /**
 | 
			
		||||
		 * decode base64 data to ArrayBuffer
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param  {string}      data data to decode
 | 
			
		||||
		 * @return {ArrayBuffer}      decoded data
 | 
			
		||||
		 */
 | 
			
		||||
		function base64_to_array_buffer(data) {
 | 
			
		||||
			return Uint8Array.from(atob(data), c => c.charCodeAt(0)).buffer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * request publicKeyCredentialCreationOptions for webauthn from server
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return {Promise<Object>} A promise that resolves with publicKeyCredentialCreationOptions for navigator.credentials.create()
 | 
			
		||||
	 */
 | 
			
		||||
	function get_pkcco() {
 | 
			
		||||
		return fetch("{{ url_for('frontend.webauthn_pkcco_route')}}", {method:'post',  headers: {'Content-Type': 'application/json'}})
 | 
			
		||||
      .then(function(resp) {
 | 
			
		||||
        return resp.text();
 | 
			
		||||
      })
 | 
			
		||||
      .then(function(data){
 | 
			
		||||
        var pkcco = CBOR.decode(base64_to_array_buffer(data));
 | 
			
		||||
        console.debug('credentials.create options:', pkcco);
 | 
			
		||||
        
 | 
			
		||||
var publicKey = {
 | 
			
		||||
  // The challenge is produced by the server; see the Security Considerations
 | 
			
		||||
  challenge: new Uint8Array([21,31,105 /* 29 more random bytes generated by the server */]),
 | 
			
		||||
 | 
			
		||||
  // Relying Party:
 | 
			
		||||
  rp: {
 | 
			
		||||
    name: "Lenticular Cloud - domain TODO"
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  // User:
 | 
			
		||||
  user: {
 | 
			
		||||
    id: Uint8Array.from(window.atob("MIIBkzCCATigAwIBAjCCAZMwggE4oAMCAQIwggGTMII="), c=>c.charCodeAt(0)),
 | 
			
		||||
    name: "{user.domain}",
 | 
			
		||||
    displayName: "{user.name}",
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  // This Relying Party will accept either an ES256 or RS256 credential, but
 | 
			
		||||
  // prefers an ES256 credential.
 | 
			
		||||
  pubKeyCredParams: [
 | 
			
		||||
    {
 | 
			
		||||
      type: "public-key",
 | 
			
		||||
      alg: -7 // "ES256" as registered in the IANA COSE Algorithms registry
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: "public-key",
 | 
			
		||||
      alg: -257 // Value registered by this specification for "RS256"
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
 | 
			
		||||
  authenticatorSelection: {
 | 
			
		||||
    // Try to use UV if possible. This is also the default.
 | 
			
		||||
    userVerification: "preferred"
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  timeout: 360000,  // 6 minutes
 | 
			
		||||
  excludeCredentials: [
 | 
			
		||||
    // Don’t re-register any authenticator that has one of these credentials
 | 
			
		||||
    //{"id": Uint8Array.from(window.atob("E/e1dhZc++mIsz4f9hb6NifAzJpF1V4mEtRlIPBiWdY="), c=>c.charCodeAt(0)), "type": "public-key"}
 | 
			
		||||
  ],
 | 
			
		||||
 | 
			
		||||
  // Make excludeCredentials check backwards compatible with credentials registered with U2F
 | 
			
		||||
  extensions: {"appidExclude": "https://acme.example.com"}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
return { "publicKey": publicKey };
 | 
			
		||||
      })
 | 
			
		||||
      .catch(function(error) { console.log('cant get pkcco ',error)});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * pack attestation
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param {object} attestation attestation response for the credential to register
 | 
			
		||||
	 */
 | 
			
		||||
	function pack_attestation(attestation) {
 | 
			
		||||
		console.debug('new credential attestation:', attestation);
 | 
			
		||||
 | 
			
		||||
		var attestation_data = {
 | 
			
		||||
			'clientDataJSON': new Uint8Array(attestation.response.clientDataJSON),
 | 
			
		||||
			'attestationObject': new Uint8Array(attestation.response.attestationObject)
 | 
			
		||||
		};
 | 
			
		||||
    //var form = $('#webauthn_register_form')[0];
 | 
			
		||||
    var form = document.querySelector('form')
 | 
			
		||||
    var base64 = btoa(new Uint8Array(CBOR.encode(attestation_data)).reduce((data, byte) => data + String.fromCharCode(byte), ''));
 | 
			
		||||
		form.attestation.value = base64;
 | 
			
		||||
		form.submit.disabled = false;
 | 
			
		||||
    //form.querySelecotr('p[name="attestation_data_status"]').innerHTML = '<span style="color: green;">Prepared</span>';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  console.log(window.PublicKeyCredential ? 'WebAuthn supported' : 'WebAuthn NOT supported');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  get_pkcco()
 | 
			
		||||
  .then(pkcco => navigator.credentials.create(pkcco))
 | 
			
		||||
  .then(attestation_response => pack_attestation(attestation_response))
 | 
			
		||||
  .catch(function(error) {
 | 
			
		||||
    //toastr.error('Registration data preparation failed.');
 | 
			
		||||
    console.log(error.message);
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
<div class="profile">
 | 
			
		||||
	<h1>Register new Webauthn credential</h1>
 | 
			
		||||
 | 
			
		||||
	<div>
 | 
			
		||||
		To register new credential:
 | 
			
		||||
		<ol>
 | 
			
		||||
			<li>Insert/connect authenticator and verify user presence.</li>
 | 
			
		||||
			<li>Optionaly set comment for the new credential.</li>
 | 
			
		||||
			<li>Submit the registration.</li>
 | 
			
		||||
		</ol>
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
  {{ render_form(form) }}
 | 
			
		||||
  {#
 | 
			
		||||
	<form id="webauthn_register_form" class="form-horizontal" method="post">
 | 
			
		||||
		{{ form.csrf_token }}
 | 
			
		||||
		<div class="form-group">
 | 
			
		||||
			<label class="col-sm-2 control-label">Registration data</label>
 | 
			
		||||
			<div class="col-sm-10"><p class="form-control-static" name="attestation_data_status"><span style="color: orange;">To be prepared</span></p></div>
 | 
			
		||||
		</div>
 | 
			
		||||
		{{ b_wtf.bootstrap_field(form.attestation, horizontal=True) }}
 | 
			
		||||
		{{ b_wtf.bootstrap_field(form.name, horizontal=True) }}
 | 
			
		||||
		{{ b_wtf.bootstrap_field(form.submit, horizontal=True) }}
 | 
			
		||||
  </form>
 | 
			
		||||
  #}
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue