first commit
This commit is contained in:
14
media/plg_multifactorauth_webauthn/images/passkeys.svg
Normal file
14
media/plg_multifactorauth_webauthn/images/passkeys.svg
Normal file
@ -0,0 +1,14 @@
|
||||
<svg width="113" viewBox="0 0 112 30" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="-4" y="-2" width="119.522" height="34.182" style="fill:none;"/>
|
||||
<g>
|
||||
<path d="M12.648,0.445c3.829,0 6.937,3.109 6.937,6.938c0,3.829 -3.108,6.937 -6.937,6.937c-3.829,0 -6.937,-3.108 -6.937,-6.937c-0,-3.829 3.108,-6.938 6.937,-6.938Zm18.5,13.875c-0.004,2.223 -1.38,4.226 -3.454,5.026l1.912,1.911l-2.313,2.313l2.313,2.312l-3.854,3.854l-2.313,-2.312l0,-8.248c-1.879,-0.891 -3.083,-2.794 -3.083,-4.875c0,-2.96 2.436,-5.396 5.396,-5.396c2.96,0 5.396,2.436 5.396,5.396c-0,0.006 -0,0.013 -0,0.019Zm-5.396,0c0.846,0 1.541,-0.696 1.541,-1.542c0,-0.845 -0.695,-1.541 -1.541,-1.541c-0.846,-0 -1.542,0.696 -1.542,1.541c0,0.846 0.696,1.542 1.542,1.542Zm-7.03,3.114c0.539,1.195 1.365,2.239 2.405,3.037l-0,8.495l-20.041,-0l-0,-3.084c-0,-5.074 4.175,-9.249 9.25,-9.249l4.624,-0c1.297,0 2.578,0.273 3.762,0.801Z"/>
|
||||
<path d="M44.369,16.591l-2.438,-0l-0,4.129l-2.385,0l0,-11.485l5.003,0c1.153,0 2.072,0.296 2.758,0.888c0.686,0.593 1.028,1.509 1.028,2.751c0,1.356 -0.342,2.314 -1.028,2.875c-0.686,0.561 -1.665,0.842 -2.938,0.842Zm1.122,-2.392c0.312,-0.276 0.468,-0.712 0.468,-1.309c-0,-0.598 -0.157,-1.024 -0.472,-1.278c-0.314,-0.255 -0.754,-0.382 -1.32,-0.382l-2.236,-0l-0,3.382l2.236,-0c0.566,-0 1.007,-0.138 1.324,-0.413Z" style="fill-rule:nonzero;"/>
|
||||
<path d="M50.275,13.147c0.587,-0.748 1.595,-1.122 3.024,-1.122c0.93,-0 1.755,0.184 2.477,0.553c0.723,0.369 1.084,1.065 1.084,2.088l-0,3.896c-0,0.27 0.005,0.597 0.015,0.982c0.016,0.291 0.06,0.488 0.133,0.592c0.072,0.104 0.181,0.189 0.327,0.257l-0,0.327l-2.416,0c-0.067,-0.171 -0.114,-0.332 -0.14,-0.483c-0.026,-0.15 -0.047,-0.322 -0.062,-0.514c-0.307,0.332 -0.66,0.615 -1.06,0.849c-0.478,0.276 -1.018,0.413 -1.621,0.413c-0.768,0 -1.403,-0.219 -1.905,-0.658c-0.501,-0.439 -0.752,-1.061 -0.752,-1.866c0,-1.044 0.403,-1.8 1.208,-2.268c0.442,-0.254 1.091,-0.436 1.948,-0.545l0.756,-0.094c0.41,-0.052 0.704,-0.117 0.88,-0.194c0.317,-0.136 0.476,-0.346 0.476,-0.632c-0,-0.348 -0.121,-0.588 -0.363,-0.72c-0.241,-0.133 -0.596,-0.199 -1.063,-0.199c-0.525,-0 -0.896,0.13 -1.114,0.39c-0.156,0.192 -0.26,0.451 -0.312,0.779l-2.143,-0c0.047,-0.743 0.255,-1.353 0.623,-1.831Zm1.652,5.968c0.208,0.172 0.463,0.257 0.764,0.257c0.478,0 0.918,-0.14 1.321,-0.42c0.402,-0.281 0.611,-0.793 0.627,-1.535l-0,-0.826c-0.14,0.088 -0.282,0.159 -0.425,0.214c-0.143,0.054 -0.339,0.105 -0.588,0.152l-0.499,0.093c-0.467,0.083 -0.802,0.185 -1.005,0.304c-0.343,0.203 -0.514,0.517 -0.514,0.943c-0,0.379 0.106,0.652 0.319,0.818Z" style="fill-rule:nonzero;"/>
|
||||
<path d="M64.683,12.617c0.664,0.426 1.046,1.158 1.145,2.197l-2.221,0c-0.031,-0.286 -0.111,-0.512 -0.241,-0.678c-0.244,-0.301 -0.66,-0.452 -1.247,-0.452c-0.483,0 -0.827,0.076 -1.032,0.226c-0.206,0.151 -0.308,0.328 -0.308,0.53c-0,0.255 0.109,0.439 0.327,0.553c0.218,0.12 0.99,0.325 2.314,0.616c0.883,0.208 1.546,0.522 1.987,0.943c0.436,0.426 0.655,0.958 0.655,1.597c-0,0.841 -0.313,1.528 -0.939,2.061c-0.626,0.532 -1.594,0.799 -2.903,0.799c-1.335,-0 -2.32,-0.282 -2.957,-0.846c-0.636,-0.563 -0.954,-1.282 -0.954,-2.154l2.252,-0c0.046,0.395 0.148,0.675 0.304,0.841c0.275,0.296 0.784,0.444 1.527,0.444c0.436,0 0.783,-0.065 1.04,-0.194c0.257,-0.13 0.386,-0.325 0.386,-0.585c-0,-0.249 -0.104,-0.439 -0.312,-0.569c-0.208,-0.129 -0.979,-0.353 -2.314,-0.67c-0.961,-0.239 -1.639,-0.537 -2.034,-0.896c-0.395,-0.353 -0.592,-0.862 -0.592,-1.527c-0,-0.784 0.308,-1.458 0.923,-2.022c0.616,-0.564 1.482,-0.845 2.599,-0.845c1.06,-0 1.924,0.21 2.595,0.631Z" style="fill-rule:nonzero;"/>
|
||||
<path d="M73.557,12.617c0.665,0.426 1.047,1.158 1.146,2.197l-2.221,0c-0.031,-0.286 -0.112,-0.512 -0.241,-0.678c-0.245,-0.301 -0.66,-0.452 -1.247,-0.452c-0.483,0 -0.827,0.076 -1.033,0.226c-0.205,0.151 -0.307,0.328 -0.307,0.53c-0,0.255 0.109,0.439 0.327,0.553c0.218,0.12 0.989,0.325 2.314,0.616c0.883,0.208 1.545,0.522 1.987,0.943c0.436,0.426 0.654,0.958 0.654,1.597c0,0.841 -0.312,1.528 -0.938,2.061c-0.626,0.532 -1.594,0.799 -2.903,0.799c-1.335,-0 -2.321,-0.282 -2.957,-0.846c-0.636,-0.563 -0.954,-1.282 -0.954,-2.154l2.251,-0c0.047,0.395 0.149,0.675 0.304,0.841c0.276,0.296 0.785,0.444 1.528,0.444c0.436,0 0.783,-0.065 1.04,-0.194c0.257,-0.13 0.385,-0.325 0.385,-0.585c0,-0.249 -0.103,-0.439 -0.311,-0.569c-0.208,-0.129 -0.979,-0.353 -2.314,-0.67c-0.961,-0.239 -1.639,-0.537 -2.034,-0.896c-0.395,-0.353 -0.592,-0.862 -0.592,-1.527c-0,-0.784 0.308,-1.458 0.923,-2.022c0.616,-0.564 1.482,-0.845 2.599,-0.845c1.059,-0 1.924,0.21 2.594,0.631Z" style="fill-rule:nonzero;"/>
|
||||
<path d="M84.372,20.72l-2.68,0l-2.034,-3.631l-0.919,0.959l-0,2.672l-2.182,0l0,-11.446l2.182,0l-0,6.187l2.766,-3.195l2.75,0l-2.968,3.249l3.085,5.205Z" style="fill-rule:nonzero;"/>
|
||||
<path d="M92.725,18.227c-0.057,0.504 -0.319,1.015 -0.787,1.535c-0.727,0.826 -1.745,1.239 -3.054,1.239c-1.081,-0 -2.034,-0.348 -2.86,-1.044c-0.826,-0.696 -1.239,-1.829 -1.239,-3.398c0,-1.47 0.373,-2.597 1.118,-3.381c0.746,-0.785 1.713,-1.177 2.903,-1.177c0.706,0 1.343,0.133 1.909,0.398c0.566,0.265 1.034,0.683 1.402,1.254c0.333,0.504 0.548,1.088 0.647,1.753c0.057,0.39 0.081,0.951 0.07,1.683l-5.812,0c0.031,0.852 0.298,1.45 0.802,1.792c0.307,0.213 0.675,0.32 1.107,0.32c0.457,-0 0.828,-0.13 1.114,-0.39c0.156,-0.14 0.293,-0.335 0.413,-0.584l2.267,-0Zm-2.197,-2.603c-0.037,-0.587 -0.214,-1.032 -0.534,-1.336c-0.319,-0.304 -0.715,-0.456 -1.188,-0.456c-0.514,0 -0.913,0.161 -1.196,0.483c-0.283,0.322 -0.461,0.759 -0.534,1.309l3.452,0Z" style="fill-rule:nonzero;"/>
|
||||
<path d="M97.782,18.492l1.753,-6.265l2.361,0l-2.914,8.353c-0.561,1.61 -1.005,2.609 -1.332,2.996c-0.328,0.387 -0.982,0.58 -1.964,0.58c-0.197,0 -0.356,-0.001 -0.475,-0.003c-0.12,-0.003 -0.299,-0.012 -0.538,-0.028l0,-1.776l0.281,0.015c0.218,0.011 0.426,0.003 0.623,-0.023c0.197,-0.026 0.364,-0.086 0.499,-0.179c0.129,-0.089 0.25,-0.273 0.362,-0.553c0.112,-0.281 0.157,-0.452 0.136,-0.515l-3.116,-8.867l2.47,0l1.854,6.265Z" style="fill-rule:nonzero;"/>
|
||||
<path d="M109.057,12.617c0.665,0.426 1.046,1.158 1.145,2.197l-2.221,0c-0.031,-0.286 -0.111,-0.512 -0.241,-0.678c-0.244,-0.301 -0.66,-0.452 -1.247,-0.452c-0.483,0 -0.827,0.076 -1.032,0.226c-0.205,0.151 -0.308,0.328 -0.308,0.53c0,0.255 0.109,0.439 0.327,0.553c0.218,0.12 0.99,0.325 2.314,0.616c0.884,0.208 1.546,0.522 1.987,0.943c0.437,0.426 0.655,0.958 0.655,1.597c-0,0.841 -0.313,1.528 -0.939,2.061c-0.626,0.532 -1.593,0.799 -2.902,0.799c-1.335,-0 -2.321,-0.282 -2.957,-0.846c-0.637,-0.563 -0.955,-1.282 -0.955,-2.154l2.252,-0c0.047,0.395 0.148,0.675 0.304,0.841c0.275,0.296 0.784,0.444 1.527,0.444c0.436,0 0.783,-0.065 1.04,-0.194c0.257,-0.13 0.386,-0.325 0.386,-0.585c-0,-0.249 -0.104,-0.439 -0.312,-0.569c-0.208,-0.129 -0.979,-0.353 -2.314,-0.67c-0.961,-0.239 -1.639,-0.537 -2.034,-0.896c-0.394,-0.353 -0.592,-0.862 -0.592,-1.527c0,-0.784 0.308,-1.458 0.923,-2.022c0.616,-0.564 1.482,-0.845 2.599,-0.845c1.06,-0 1.925,0.21 2.595,0.631Z" style="fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.7 KiB |
1
media/plg_multifactorauth_webauthn/images/webauthn.svg
Normal file
1
media/plg_multifactorauth_webauthn/images/webauthn.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 6.8 KiB |
21
media/plg_multifactorauth_webauthn/joomla.asset.json
Normal file
21
media/plg_multifactorauth_webauthn/joomla.asset.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json",
|
||||
"name": "plg_multifactorauth_webauthn",
|
||||
"version": "4.0.0",
|
||||
"description": "WebAuthn integration for Joomla Multi-factor Authentication",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"assets": [
|
||||
{
|
||||
"name": "plg_multifactorauth_webauthn.webauthn",
|
||||
"type": "script",
|
||||
"uri": "plg_multifactorauth_webauthn/webauthn.min.js",
|
||||
"dependencies": [
|
||||
"core"
|
||||
],
|
||||
"attributes": {
|
||||
"defer": true
|
||||
},
|
||||
"version": "8bda04"
|
||||
}
|
||||
]
|
||||
}
|
||||
148
media/plg_multifactorauth_webauthn/js/webauthn.js
Normal file
148
media/plg_multifactorauth_webauthn/js/webauthn.js
Normal file
@ -0,0 +1,148 @@
|
||||
/**
|
||||
* @package Joomla.Plugin
|
||||
* @subpackage Multifactorauth.webauthn
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
((Joomla, document) => {
|
||||
|
||||
let authData = null;
|
||||
const arrayToBase64String = a => btoa(String.fromCharCode(...a));
|
||||
const base64url2base64 = input => {
|
||||
let output = input.replace(/-/g, '+').replace(/_/g, '/');
|
||||
const pad = output.length % 4;
|
||||
if (pad) {
|
||||
if (pad === 1) {
|
||||
throw new Error('InvalidLengthError: Input base64url string is the wrong length to determine padding');
|
||||
}
|
||||
output += new Array(5 - pad).join('=');
|
||||
}
|
||||
return output;
|
||||
};
|
||||
const displayError = message => {
|
||||
try {
|
||||
Joomla.renderMessages({
|
||||
error: message
|
||||
});
|
||||
} catch (e) {
|
||||
alert(message);
|
||||
}
|
||||
};
|
||||
const handleError = message => {
|
||||
try {
|
||||
document.getElementById('plg_multifactorauth_webauthn_validate_button').style.disabled = 'null';
|
||||
} catch (e) {
|
||||
// Do nothing
|
||||
}
|
||||
displayError(message);
|
||||
};
|
||||
const setUp = e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Make sure the browser supports Webauthn
|
||||
if (!('credentials' in navigator)) {
|
||||
displayError(Joomla.Text._('PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_NOTAVAILABLE_HEAD'));
|
||||
return false;
|
||||
}
|
||||
const rawPKData = document.forms['com-users-method-edit'].querySelectorAll('input[name="pkRequest"]')[0].value;
|
||||
const publicKey = JSON.parse(atob(rawPKData));
|
||||
|
||||
// Convert the public key information to a format usable by the browser's credentials manager
|
||||
publicKey.challenge = Uint8Array.from(window.atob(base64url2base64(publicKey.challenge)), c => c.charCodeAt(0));
|
||||
publicKey.user.id = Uint8Array.from(window.atob(publicKey.user.id), c => c.charCodeAt(0));
|
||||
if (publicKey.excludeCredentials) {
|
||||
publicKey.excludeCredentials = publicKey.excludeCredentials.map(data => {
|
||||
data.id = Uint8Array.from(window.atob(base64url2base64(data.id)), c => c.charCodeAt(0));
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
// Ask the browser to prompt the user for their authenticator
|
||||
navigator.credentials.create({
|
||||
publicKey
|
||||
}).then(data => {
|
||||
const publicKeyCredential = {
|
||||
id: data.id,
|
||||
type: data.type,
|
||||
rawId: arrayToBase64String(new Uint8Array(data.rawId)),
|
||||
response: {
|
||||
clientDataJSON: arrayToBase64String(new Uint8Array(data.response.clientDataJSON)),
|
||||
attestationObject: arrayToBase64String(new Uint8Array(data.response.attestationObject))
|
||||
}
|
||||
};
|
||||
|
||||
// Store the WebAuthn reply
|
||||
document.getElementById('com-users-method-code').value = btoa(JSON.stringify(publicKeyCredential));
|
||||
|
||||
// Submit the form
|
||||
document.forms['com-users-method-edit'].submit();
|
||||
}, error => {
|
||||
// An error occurred: timeout, request to provide the authenticator refused, hardware / software
|
||||
// error...
|
||||
handleError(error);
|
||||
});
|
||||
return false;
|
||||
};
|
||||
const validate = () => {
|
||||
// Make sure the browser supports Webauthn
|
||||
if (!('credentials' in navigator)) {
|
||||
displayError(Joomla.Text._('PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_NOTAVAILABLE_HEAD'));
|
||||
return;
|
||||
}
|
||||
const publicKey = authData;
|
||||
if (!publicKey.challenge) {
|
||||
handleError(Joomla.Text._('PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_NO_STORED_CREDENTIAL'));
|
||||
return;
|
||||
}
|
||||
publicKey.challenge = Uint8Array.from(window.atob(base64url2base64(publicKey.challenge)), c => c.charCodeAt(0));
|
||||
if (publicKey.allowCredentials) {
|
||||
publicKey.allowCredentials = publicKey.allowCredentials.map(data => {
|
||||
data.id = Uint8Array.from(window.atob(base64url2base64(data.id)), c => c.charCodeAt(0));
|
||||
return data;
|
||||
});
|
||||
}
|
||||
navigator.credentials.get({
|
||||
publicKey
|
||||
}).then(data => {
|
||||
const publicKeyCredential = {
|
||||
id: data.id,
|
||||
type: data.type,
|
||||
rawId: arrayToBase64String(new Uint8Array(data.rawId)),
|
||||
response: {
|
||||
authenticatorData: arrayToBase64String(new Uint8Array(data.response.authenticatorData)),
|
||||
clientDataJSON: arrayToBase64String(new Uint8Array(data.response.clientDataJSON)),
|
||||
signature: arrayToBase64String(new Uint8Array(data.response.signature)),
|
||||
userHandle: data.response.userHandle ? arrayToBase64String(new Uint8Array(data.response.userHandle)) : null
|
||||
}
|
||||
};
|
||||
document.getElementById('users-mfa-code').value = btoa(JSON.stringify(publicKeyCredential));
|
||||
document.getElementById('users-mfa-captive-form').submit();
|
||||
}, error => {
|
||||
// Example: timeout, interaction refused...
|
||||
handleError(error);
|
||||
});
|
||||
};
|
||||
const onValidateClick = event => {
|
||||
event.preventDefault();
|
||||
authData = JSON.parse(window.atob(Joomla.getOptions('com_users.authData')));
|
||||
document.getElementById('users-mfa-captive-button-submit').style.disabled = 'disabled';
|
||||
validate();
|
||||
return false;
|
||||
};
|
||||
document.getElementById('multifactorauth-webauthn-missing').style.display = 'none';
|
||||
if (typeof navigator.credentials === 'undefined') {
|
||||
document.getElementById('multifactorauth-webauthn-missing').style.display = 'block';
|
||||
document.getElementById('multifactorauth-webauthn-controls').style.display = 'none';
|
||||
}
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
if (Joomla.getOptions('com_users.pagetype') === 'validate') {
|
||||
document.getElementById('users-mfa-captive-button-submit').addEventListener('click', onValidateClick);
|
||||
} else {
|
||||
document.querySelectorAll('.multifactorauth_webauthn_setup').forEach(btn => {
|
||||
btn.addEventListener('click', setUp);
|
||||
});
|
||||
}
|
||||
});
|
||||
})(Joomla, document);
|
||||
1
media/plg_multifactorauth_webauthn/js/webauthn.min.js
vendored
Normal file
1
media/plg_multifactorauth_webauthn/js/webauthn.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
((e,t)=>{let a=null;const n=e=>btoa(String.fromCharCode(...e)),r=e=>{let t=e.replace(/-/g,"+").replace(/_/g,"/");const a=t.length%4;if(a){if(1===a)throw new Error("InvalidLengthError: Input base64url string is the wrong length to determine padding");t+=new Array(5-a).join("=")}return t},i=t=>{try{e.renderMessages({error:t})}catch(e){alert(t)}},o=e=>{try{t.getElementById("plg_multifactorauth_webauthn_validate_button").style.disabled="null"}catch(e){}i(e)},s=a=>{if(a.preventDefault(),!("credentials"in navigator))return i(e.Text._("PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_NOTAVAILABLE_HEAD")),!1;const s=t.forms["com-users-method-edit"].querySelectorAll('input[name="pkRequest"]')[0].value,l=JSON.parse(atob(s));return l.challenge=Uint8Array.from(window.atob(r(l.challenge)),(e=>e.charCodeAt(0))),l.user.id=Uint8Array.from(window.atob(l.user.id),(e=>e.charCodeAt(0))),l.excludeCredentials&&(l.excludeCredentials=l.excludeCredentials.map((e=>(e.id=Uint8Array.from(window.atob(r(e.id)),(e=>e.charCodeAt(0))),e)))),navigator.credentials.create({publicKey:l}).then((e=>{const a={id:e.id,type:e.type,rawId:n(new Uint8Array(e.rawId)),response:{clientDataJSON:n(new Uint8Array(e.response.clientDataJSON)),attestationObject:n(new Uint8Array(e.response.attestationObject))}};t.getElementById("com-users-method-code").value=btoa(JSON.stringify(a)),t.forms["com-users-method-edit"].submit()}),(e=>{o(e)})),!1},l=s=>(s.preventDefault(),a=JSON.parse(window.atob(e.getOptions("com_users.authData"))),t.getElementById("users-mfa-captive-button-submit").style.disabled="disabled",(()=>{if(!("credentials"in navigator))return void i(e.Text._("PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_NOTAVAILABLE_HEAD"));const s=a;s.challenge?(s.challenge=Uint8Array.from(window.atob(r(s.challenge)),(e=>e.charCodeAt(0))),s.allowCredentials&&(s.allowCredentials=s.allowCredentials.map((e=>(e.id=Uint8Array.from(window.atob(r(e.id)),(e=>e.charCodeAt(0))),e)))),navigator.credentials.get({publicKey:s}).then((e=>{const a={id:e.id,type:e.type,rawId:n(new Uint8Array(e.rawId)),response:{authenticatorData:n(new Uint8Array(e.response.authenticatorData)),clientDataJSON:n(new Uint8Array(e.response.clientDataJSON)),signature:n(new Uint8Array(e.response.signature)),userHandle:e.response.userHandle?n(new Uint8Array(e.response.userHandle)):null}};t.getElementById("users-mfa-code").value=btoa(JSON.stringify(a)),t.getElementById("users-mfa-captive-form").submit()}),(e=>{o(e)}))):o(e.Text._("PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_NO_STORED_CREDENTIAL"))})(),!1);t.getElementById("multifactorauth-webauthn-missing").style.display="none",void 0===navigator.credentials&&(t.getElementById("multifactorauth-webauthn-missing").style.display="block",t.getElementById("multifactorauth-webauthn-controls").style.display="none"),window.addEventListener("DOMContentLoaded",(()=>{"validate"===e.getOptions("com_users.pagetype")?t.getElementById("users-mfa-captive-button-submit").addEventListener("click",l):t.querySelectorAll(".multifactorauth_webauthn_setup").forEach((e=>{e.addEventListener("click",s)}))}))})(Joomla,document);
|
||||
BIN
media/plg_multifactorauth_webauthn/js/webauthn.min.js.gz
Normal file
BIN
media/plg_multifactorauth_webauthn/js/webauthn.min.js.gz
Normal file
Binary file not shown.
Reference in New Issue
Block a user