All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			
		
			
				
	
	
		
			91 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
{% extends "base_settings_page.html" %}
 | 
						|
{% block content %}
 | 
						|
<div style="max-width: 700px;">
 | 
						|
 | 
						|
    <p>In order to continue, please click on the "Start Enrollment" button, insert your security key and approve the
 | 
						|
        registration request.</p>
 | 
						|
 | 
						|
    <div class="form-group">
 | 
						|
        <label for="inputKeyName" class="form-label mt-4">Key name</label>
 | 
						|
        <input type="text" class="form-control" id="inputKeyName"
 | 
						|
               placeholder="Device / Authenticator app name"
 | 
						|
               value="Security key" minlength="1" maxlength="{{ max_name_len }}" required/>
 | 
						|
        <small class="form-text text-muted">Please give a name to your key to identify it more easily later.</small>
 | 
						|
        <div class="invalid-feedback">Please give a name to this security key</div>
 | 
						|
    </div>
 | 
						|
 | 
						|
    <input type="button" class="btn btn-primary" value="Start enrollment" onclick="startEnrollment()"
 | 
						|
           style="margin-top: 20px;" id="submitButton" />
 | 
						|
 | 
						|
    <script src="/assets/js/base64_lib.js"></script>
 | 
						|
    <script>
 | 
						|
        const OPAQUE_STATE = "{{ opaque_state }}";
 | 
						|
        const REGISTRATION_CHALLENGE = JSON.parse(decodeURIComponent("{{ challenge_json }}"));
 | 
						|
 | 
						|
        // Decode data
 | 
						|
        REGISTRATION_CHALLENGE.publicKey.challenge = base64NoPaddingToUint8Array(
 | 
						|
			REGISTRATION_CHALLENGE.publicKey.challenge
 | 
						|
		);
 | 
						|
		REGISTRATION_CHALLENGE.publicKey.user.id = base64NoPaddingToUint8Array(
 | 
						|
			REGISTRATION_CHALLENGE.publicKey.user.id
 | 
						|
		);
 | 
						|
 | 
						|
        const submitButton = document.getElementById("submitButton");
 | 
						|
 | 
						|
        async function startEnrollment() {
 | 
						|
            submitButton.disabled = true;
 | 
						|
            try {
 | 
						|
                const factorNameInput = document.getElementById("inputKeyName");
 | 
						|
                factorNameInput.classList.remove("is-invalid");
 | 
						|
                if (factorNameInput.value.length === 0) {
 | 
						|
                    factorNameInput.classList.add("is-invalid");
 | 
						|
                    return;
 | 
						|
                }
 | 
						|
 | 
						|
                const cred = await navigator.credentials.create(REGISTRATION_CHALLENGE);
 | 
						|
 | 
						|
                // Encode data that needs to be encoded
 | 
						|
                const credential_res = {
 | 
						|
                    id: cred.id,
 | 
						|
                    rawId: ArrayBufferToBase64(cred.rawId),
 | 
						|
                    type: cred.type,
 | 
						|
                    response: {
 | 
						|
                        attestationObject: ArrayBufferToBase64(
 | 
						|
                            cred.response.attestationObject
 | 
						|
                        ),
 | 
						|
                        clientDataJSON: ArrayBufferToBase64(
 | 
						|
                            cred.response.clientDataJSON
 | 
						|
                        ),
 | 
						|
                    },
 | 
						|
                };
 | 
						|
 | 
						|
                const res = await fetch("/settings/api/two_factor/save_webauthn_factor", {
 | 
						|
                    method: "post",
 | 
						|
                    headers: {
 | 
						|
                      'Content-Type': 'application/json',
 | 
						|
                    },
 | 
						|
                    body: JSON.stringify({
 | 
						|
                        opaque_state: OPAQUE_STATE,
 | 
						|
                        factor_name: factorNameInput.value,
 | 
						|
                        credential: credential_res,
 | 
						|
                    })
 | 
						|
                });
 | 
						|
 | 
						|
                let text = await res.text();
 | 
						|
                alert(text);
 | 
						|
 | 
						|
                if (res.status == 200)
 | 
						|
                    location.href = "/settings/two_factors";
 | 
						|
            } catch(e) {
 | 
						|
                console.error(e);
 | 
						|
                alert("Failed enrollment, please try again!");
 | 
						|
            } finally {
 | 
						|
                submitButton.disabled = false;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    </script>
 | 
						|
 | 
						|
</div>
 | 
						|
 | 
						|
{% endblock content %}
 |