Compare commits
4 Commits
v3.0
...
Conditiona
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcad5d3818 | ||
|
|
1cfddde23b | ||
|
|
0ab710e503 | ||
|
|
52e307ef0e |
19
README.md
19
README.md
@@ -194,6 +194,25 @@ function some_func() {
|
|||||||
|
|
||||||
````
|
````
|
||||||
|
|
||||||
|
# Using ConditionalUI
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
ConditionalUI is a cutting-edge feature that allows the user to use the browser autofill feature available in the browser to login using the FIDO2.
|
||||||
|
|
||||||
|
Currently available on Safari on iOS 16+, Safari on Ventura, Chrome on Android (Using Play Services Beta), Chrome Canary on Both Mac OS X and Windows.
|
||||||
|
|
||||||
|
To Use this feature
|
||||||
|
1. set `MFA_FIDO2_RESIDENT_KEY` to `mfa.ResidentKey.REQUIRED`
|
||||||
|
2. set the autocomplete of username field to `username webauth` as follows
|
||||||
|
```html
|
||||||
|
<input type="text" name="username" autocomplete="username webauthn" ...>
|
||||||
|
```
|
||||||
|
3. Finally, Include `FIDO2/FormFill.html` in your login form
|
||||||
|
```html
|
||||||
|
{% include 'FIDO2/FormFill.html' %}
|
||||||
|
```
|
||||||
|
|
||||||
# Contributors
|
# Contributors
|
||||||
* [mahmoodnasr](https://github.com/mahmoodnasr)
|
* [mahmoodnasr](https://github.com/mahmoodnasr)
|
||||||
* [d3cline](https://github.com/d3cline)
|
* [d3cline](https://github.com/d3cline)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="form-label-group">
|
<div class="form-label-group">
|
||||||
<input type="text" id="inputUsername" name="username" class="form-control" placeholder="username" required="required" autofocus="autofocus">
|
<input type="text" id="inputUsername" name="username" class="form-control" placeholder="username" required autofocus autocomplete="username webauthn">
|
||||||
<label for="inputUsername">Username</label>
|
<label for="inputUsername">Username</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -46,8 +46,9 @@
|
|||||||
|
|
||||||
<button class="btn btn-primary btn-block" type="submit">Login</button><br/>
|
<button class="btn btn-primary btn-block" type="submit">Login</button><br/>
|
||||||
|
|
||||||
<button class="btn btn-primary btn-block" type="button" onclick="authen()">Login By Security Key</button>
|
|
||||||
</form>
|
</form>
|
||||||
|
<button class="btn btn-primary btn-block" onclick="authen()">Login By PassKeys</button><br/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -58,7 +59,9 @@
|
|||||||
|
|
||||||
<!-- Core plugin JavaScript-->
|
<!-- Core plugin JavaScript-->
|
||||||
<script src="{% static 'vendor/jquery-easing/jquery.easing.min.js'%}"></script>
|
<script src="{% static 'vendor/jquery-easing/jquery.easing.min.js'%}"></script>
|
||||||
{% include 'FIDO2/Auth_JS.html'%}
|
|
||||||
|
{% include 'FIDO2/FormFill.html' %}
|
||||||
|
{# {% include 'FIDO2/Auth_JS.html' with delay=True %}#}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
BIN
img/conditionalUI.png
Normal file
BIN
img/conditionalUI.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 111 KiB |
@@ -12,8 +12,11 @@ var GetAssertReq = (getAssert) => {
|
|||||||
|
|
||||||
return getAssert
|
return getAssert
|
||||||
}
|
}
|
||||||
function authen()
|
function authen(conditionalUI=false)
|
||||||
{
|
{
|
||||||
|
if (window.hasOwnProperty("getCredSignal"))
|
||||||
|
window.getCredSignal.abort('Restarting');
|
||||||
|
window.getCredSignal = new AbortController();
|
||||||
fetch('{% url 'fido2_begin_auth' %}', {
|
fetch('{% url 'fido2_begin_auth' %}', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
}).then(function(response) {
|
}).then(function(response) {
|
||||||
@@ -25,6 +28,10 @@ var GetAssertReq = (getAssert) => {
|
|||||||
throw new Error('No credential available to authenticate!');
|
throw new Error('No credential available to authenticate!');
|
||||||
}).then(function(options) {
|
}).then(function(options) {
|
||||||
console.log(options)
|
console.log(options)
|
||||||
|
if (conditionalUI) {
|
||||||
|
options.mediation = 'conditional';
|
||||||
|
}
|
||||||
|
options.signal = window.getCredSignal.signal;
|
||||||
return navigator.credentials.get(options);
|
return navigator.credentials.get(options);
|
||||||
}).then(function(assertion) {
|
}).then(function(assertion) {
|
||||||
|
|
||||||
@@ -70,8 +77,11 @@ var GetAssertReq = (getAssert) => {
|
|||||||
ua=new UAParser().getResult()
|
ua=new UAParser().getResult()
|
||||||
if (ua.browser.name == "Safari" || ua.browser.name == "Mobile Safari" || ua.os.name == "iOS" || ua.os.name == "iPadOS")
|
if (ua.browser.name == "Safari" || ua.browser.name == "Mobile Safari" || ua.os.name == "iOS" || ua.os.name == "iPadOS")
|
||||||
$("#res").html("<button class='btn btn-success' onclick='authen()'>Authenticate...</button>")
|
$("#res").html("<button class='btn btn-success' onclick='authen()'>Authenticate...</button>")
|
||||||
else
|
else {
|
||||||
|
{% if delay != True and not conditionalUI%}
|
||||||
authen()
|
authen()
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
15
mfa/templates/FIDO2/FormFill.html
Normal file
15
mfa/templates/FIDO2/FormFill.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<script type="application/javascript">
|
||||||
|
$(document).ready(async function () {
|
||||||
|
if (window.PublicKeyCredential &&
|
||||||
|
PublicKeyCredential.isConditionalMediationAvailable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Check if conditional mediation is available.
|
||||||
|
const isCMA = await PublicKeyCredential.isConditionalMediationAvailable()
|
||||||
|
if (isCMA) {
|
||||||
|
authen(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{% include 'FIDO2/Auth_JS.html' %}
|
||||||
Reference in New Issue
Block a user