extensions/net.sf.basedb.webauthn/trunk/resources/webauthn-login.js

Code
Comments
Other
Rev Date Author Line
6770 09 Jun 22 nicklas 1 'use strict';
6750 30 May 22 nicklas 2
6750 30 May 22 nicklas 3 var WebAuthnLogin = function()
6750 30 May 22 nicklas 4 {
6750 30 May 22 nicklas 5   var wa = {};
6750 30 May 22 nicklas 6   var debug = 1;
6750 30 May 22 nicklas 7   
6750 30 May 22 nicklas 8   wa.initPage = function()
6750 30 May 22 nicklas 9   {
6759 01 Jun 22 nicklas 10     if (navigator.credentials && navigator.credentials.get)
6759 01 Jun 22 nicklas 11     {
6759 01 Jun 22 nicklas 12       var frm = document.forms['login'];
6759 01 Jun 22 nicklas 13       Events.addEventHandler(frm, 'before-login', wa.startWebAuthnLogin);
6759 01 Jun 22 nicklas 14     }
6759 01 Jun 22 nicklas 15     else
6759 01 Jun 22 nicklas 16     {
6759 01 Jun 22 nicklas 17       if (Doc.element('login-error').style.display == 'none')
6759 01 Jun 22 nicklas 18       {
6759 01 Jun 22 nicklas 19         wa.handleError('WebAuthn Security Keys are not supported by this browser!');
6759 01 Jun 22 nicklas 20       }
6759 01 Jun 22 nicklas 21     }
6750 30 May 22 nicklas 22   }
6750 30 May 22 nicklas 23
6750 30 May 22 nicklas 24   wa.handleError = function(error)
6750 30 May 22 nicklas 25   {
6750 30 May 22 nicklas 26     console.log(error);
6750 30 May 22 nicklas 27     Doc.element('login-error').innerHTML = Strings.encodeTags(error.toString ? error.toString() : error);
6750 30 May 22 nicklas 28     Doc.show('login-error');
6750 30 May 22 nicklas 29   }
6750 30 May 22 nicklas 30
6750 30 May 22 nicklas 31   // Step 1. Start the login process by sending the
6750 30 May 22 nicklas 32   // login name to the server. Since this is "async" we need to abort the
6750 30 May 22 nicklas 33   // submission of the login form.
6750 30 May 22 nicklas 34   wa.startWebAuthnLogin = function(event)
6750 30 May 22 nicklas 35   {
6750 30 May 22 nicklas 36     event.preventDefault();
6750 30 May 22 nicklas 37     var frm = document.forms['login'];
6750 30 May 22 nicklas 38     var home = Data.get(frm, 'home');
6788 05 Aug 22 nicklas 39     var passwordLess = Data.int(frm, 'password-less');
6750 30 May 22 nicklas 40     var url = home+'/WebAuthn.servlet?ID='+App.getSessionId();
6750 30 May 22 nicklas 41     url += '&cmd=StartWebAuthnLogin';
6788 05 Aug 22 nicklas 42     url += '&passwordLess='+(passwordLess?1:0);
6750 30 May 22 nicklas 43     
6788 05 Aug 22 nicklas 44     var submitData = {};
6788 05 Aug 22 nicklas 45     if (!passwordLess)
6788 05 Aug 22 nicklas 46     {
6788 05 Aug 22 nicklas 47        submitData.login = frm.login.value;
6788 05 Aug 22 nicklas 48        submitData.password = frm.password.value;
6788 05 Aug 22 nicklas 49     }
6750 30 May 22 nicklas 50     try
6750 30 May 22 nicklas 51     {
6750 30 May 22 nicklas 52       if (debug) App.debug('AJAX request: '+url);
6750 30 May 22 nicklas 53       var request = Ajax.getXmlHttpRequest();
6769 09 Jun 22 nicklas 54       request.open("POST", url, true);  
6750 30 May 22 nicklas 55       Ajax.setReadyStateHandler(request, wa.webAuthnLoginRequestRecieved, wa.webAuthnLoginRequestRecieved);
6769 09 Jun 22 nicklas 56       request.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
6788 05 Aug 22 nicklas 57       request.send(JSON.stringify(submitData));
6750 30 May 22 nicklas 58     }
6750 30 May 22 nicklas 59     catch (e)
6750 30 May 22 nicklas 60     {
6750 30 May 22 nicklas 61       wa.handleError(e);
6750 30 May 22 nicklas 62     }
6750 30 May 22 nicklas 63   }
6750 30 May 22 nicklas 64
6750 30 May 22 nicklas 65   // Step 2. Pass the response from the server to the
6750 30 May 22 nicklas 66   // navigator.credentials.get() API
6750 30 May 22 nicklas 67   wa.webAuthnLoginRequestRecieved = function(request)
6750 30 May 22 nicklas 68   {
6750 30 May 22 nicklas 69     if (debug) App.debug(request.responseText);
6750 30 May 22 nicklas 70     try
6750 30 May 22 nicklas 71     {
6750 30 May 22 nicklas 72       var response = JSON.parse(request.responseText);
6750 30 May 22 nicklas 73       if (debug) App.debug(response);
6750 30 May 22 nicklas 74       if (response.status != 'ok')
6750 30 May 22 nicklas 75       {
6750 30 May 22 nicklas 76         throw new Error(response.message);
6750 30 May 22 nicklas 77       }
6750 30 May 22 nicklas 78       
6750 30 May 22 nicklas 79       var reg = response.assertionRequest.publicKey;
6750 30 May 22 nicklas 80       
6750 30 May 22 nicklas 81       var publicKey = {
6750 30 May 22 nicklas 82         'publicKey': {
6750 30 May 22 nicklas 83           'challenge': WAUtils.base64ToUint8Array(reg.challenge),
6750 30 May 22 nicklas 84           'allowCredentials': wa.convertAllowedCredentials(reg.allowCredentials),
6788 05 Aug 22 nicklas 85           'userVerification': reg.userVerification,
6750 30 May 22 nicklas 86           'rpId': reg.rpId
6750 30 May 22 nicklas 87           }};
6750 30 May 22 nicklas 88       if (debug) App.debug(publicKey);
6750 30 May 22 nicklas 89       
6750 30 May 22 nicklas 90       navigator.credentials.get(publicKey)
6750 30 May 22 nicklas 91         .then(wa.webAuthnLoginResponseCreated)
6750 30 May 22 nicklas 92         .catch(wa.handleError);
6750 30 May 22 nicklas 93     }
6750 30 May 22 nicklas 94     catch (e)
6750 30 May 22 nicklas 95     {
6750 30 May 22 nicklas 96       wa.handleError(e);
6750 30 May 22 nicklas 97     }
6750 30 May 22 nicklas 98   }
6750 30 May 22 nicklas 99   
6750 30 May 22 nicklas 100   wa.convertAllowedCredentials = function(cred)
6750 30 May 22 nicklas 101   {
6750 30 May 22 nicklas 102     var converted = [];
6788 05 Aug 22 nicklas 103     if (cred)
6750 30 May 22 nicklas 104     {
6788 05 Aug 22 nicklas 105       for (var i = 0; i < cred.length; i++)
6788 05 Aug 22 nicklas 106       {
6788 05 Aug 22 nicklas 107         converted[i] = {
6788 05 Aug 22 nicklas 108           'id': WAUtils.base64ToUint8Array(cred[i].id),
6788 05 Aug 22 nicklas 109           'type': cred[i].type
6788 05 Aug 22 nicklas 110         }
6750 30 May 22 nicklas 111       }
6750 30 May 22 nicklas 112     }
6750 30 May 22 nicklas 113     return converted;
6750 30 May 22 nicklas 114   }
6750 30 May 22 nicklas 115   
6752 30 May 22 nicklas 116   // Step 3. Get the response from the security key and save it as JSON
6752 30 May 22 nicklas 117   // in the hidden 'extraField' and submit the login form
6750 30 May 22 nicklas 118   wa.webAuthnLoginResponseCreated = function(publicKey)
6750 30 May 22 nicklas 119   {
6752 30 May 22 nicklas 120     try
6750 30 May 22 nicklas 121     {
6752 30 May 22 nicklas 122       if (debug) 
6752 30 May 22 nicklas 123       {
6752 30 May 22 nicklas 124         App.debug(publicKey);
6788 05 Aug 22 nicklas 125         console.log('rawId: '+WAUtils.byteArrayToBase64(publicKey.rawId));
6788 05 Aug 22 nicklas 126         console.log('authenticatorData: '+WAUtils.byteArrayToBase64(publicKey.response.authenticatorData));
6788 05 Aug 22 nicklas 127         console.log('clientDataJSON: '+WAUtils.byteArrayToBase64(publicKey.response.clientDataJSON));
6788 05 Aug 22 nicklas 128         console.log('signature: '+WAUtils.byteArrayToBase64(publicKey.response.signature));
6788 05 Aug 22 nicklas 129         console.log('userHandle: '+WAUtils.byteArrayToBase64(publicKey.response.userHandle));
6752 30 May 22 nicklas 130       }
6752 30 May 22 nicklas 131       
6752 30 May 22 nicklas 132       var response = {
6752 30 May 22 nicklas 133         id: publicKey.id,
6752 30 May 22 nicklas 134         response:
6752 30 May 22 nicklas 135         {
6752 30 May 22 nicklas 136           authenticatorData: WAUtils.byteArrayToBase64(publicKey.response.authenticatorData),
6752 30 May 22 nicklas 137           clientDataJSON: WAUtils.byteArrayToBase64(publicKey.response.clientDataJSON),
6788 05 Aug 22 nicklas 138           signature: WAUtils.byteArrayToBase64(publicKey.response.signature),
6788 05 Aug 22 nicklas 139           userHandle: WAUtils.byteArrayToBase64(publicKey.response.userHandle)
6752 30 May 22 nicklas 140         },
6752 30 May 22 nicklas 141         clientExtensionResults: {},
6752 30 May 22 nicklas 142         type: 'public-key'
6752 30 May 22 nicklas 143       };
6752 30 May 22 nicklas 144   
6752 30 May 22 nicklas 145       if (debug) App.debug(response);
6752 30 May 22 nicklas 146   
6752 30 May 22 nicklas 147       var frm = document.forms['login'];
6752 30 May 22 nicklas 148       if (frm.extraField)
6752 30 May 22 nicklas 149       {
6752 30 May 22 nicklas 150         frm.extraField.value = JSON.stringify(response);
6752 30 May 22 nicklas 151       }
6752 30 May 22 nicklas 152       else
6752 30 May 22 nicklas 153       {
6752 30 May 22 nicklas 154         Forms.addHidden(frm, 'extraField', JSON.stringify(response));
6752 30 May 22 nicklas 155       }
6752 30 May 22 nicklas 156       Login.submitLoginForm();
6750 30 May 22 nicklas 157     }
6752 30 May 22 nicklas 158     catch (e)
6752 30 May 22 nicklas 159     {
6752 30 May 22 nicklas 160       wa.handleError(e);
6752 30 May 22 nicklas 161     }
6750 30 May 22 nicklas 162   }
6750 30 May 22 nicklas 163
6750 30 May 22 nicklas 164   return wa;
6750 30 May 22 nicklas 165 }();
6750 30 May 22 nicklas 166
6750 30 May 22 nicklas 167
6750 30 May 22 nicklas 168 Doc.onLoad(WebAuthnLogin.initPage);
6750 30 May 22 nicklas 169