Skip to content

Commit 34e6c6a

Browse files
committed
Merged v1.2.0
1 parent 55a2026 commit 34e6c6a

File tree

6 files changed

+46
-3
lines changed

6 files changed

+46
-3
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## v1.2
2+
3+
* Add support for Conditional UI.
4+
15
## v1.1
26

37
* `FIDO_SERVER_ID` and `FIDO_SERVER_NAME` call be callable now to multi tenants application

README.md

+21-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Currently, it support Django 2.0+, Python 3.7+
4141
FIDO_SERVER_ID="localhost" # Server rp id for FIDO2, it the full domain of your project
4242
FIDO_SERVER_NAME="TestApp"
4343
import passkeys
44-
KEY_ATTACHMENT = NONE | passkeys.Attachment.CROSS_PLATFORM | passkeys.Attachment.PLATFORM
44+
KEY_ATTACHMENT = None | passkeys.Attachment.CROSS_PLATFORM | passkeys.Attachment.PLATFORM
4545
```
4646
**Note**: Starting v1.1, `FIDO_SERVER_ID` and/or `FIDO_SERVER_NAME` can be a callable to support multi-tenants web applications, the `request` is passed to the called function.
4747
5. Add passkeys to urls.py
@@ -88,6 +88,7 @@ If the user didn't use a passkey then it will be set to False
8888
{'passkey':False}
8989
```
9090

91+
9192
# Check if the user can be enrolled for a platform authenticator
9293

9394
If you want to check if the user can be enrolled to use a platform authenticator, you can do the following in your main page.
@@ -109,6 +110,25 @@ check_passkey function paramters are as follows
109110
* `fail_func`: function to call if no platform authenticator is found (optional).
110111

111112

113+
## Using Conditional UI
114+
115+
Conditional UI is a way for the browser to prompt the user to use the passkey to login to the system as shown in
116+
117+
![conditionalUI.png](imgs%2FconditionalUI.png)
118+
119+
Starting version v1.2. you can use Conditional UI by adding the following to your login page
120+
121+
1. Add `webauthn` to autocomplete of the username field as shown below.
122+
```html
123+
<input name="username" placeholder="username" autocomplete="username webauthn">
124+
```
125+
add the following to the page js.
126+
127+
```js
128+
window.onload = checkConditionalUI('loginForm');
129+
```
130+
where `loginForm` is name of your login form.
131+
112132
## Security contact information
113133

114134
To report a security vulnerability, please use the

example/example/templates/login.html

+4-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
{% csrf_token %}
3434
<div class="form-group">
3535
<div class="form-label-group">
36-
<input type="text" id="inputUsername" name="username" class="form-control" placeholder="username" autofocus="autofocus">
36+
<input type="text" id="inputUsername" name="username" class="form-control" placeholder="username" autocomplete="username webauthn" autofocus="autofocus">
3737
<label for="inputUsername">Username</label>
3838
</div>
3939
</div>
@@ -58,6 +58,9 @@
5858

5959
<!-- Core plugin JavaScript-->
6060
<script src="{% static 'vendor/jquery-easing/jquery.easing.min.js'%}"></script>
61+
<script type="application/javascript">
62+
window.onload = checkConditionalUI('loginForm');
63+
</script>
6164

6265
</body>
6366

imgs/conditionalUI.png

102 KB
Loading

passkeys/templates/passkeys.js

+16
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22
<script type="application/javascript" src="{% static 'passkeys/js/base64url.js' %}"></script>
33
<script type="application/javascript" src="{% static 'passkeys/js/helpers.js' %}"></script>
44
<script type="text/javascript">
5+
window.conditionalUI=false;
6+
function checkConditionalUI(form) {
7+
if (window.PublicKeyCredential && PublicKeyCredential.isConditionalMediationAvailable) {
8+
// Check if conditional mediation is available.
9+
PublicKeyCredential.isConditionalMediationAvailable().then((result) => {
10+
window.conditionalUI = result;
11+
if (window.conditionalUI) {
12+
authn(form)
13+
}
14+
});
15+
}
16+
}
17+
518
var GetAssertReq = (getAssert) => {
619
getAssert.publicKey.challenge = base64url.decode(getAssert.publicKey.challenge);
720

@@ -24,6 +37,9 @@ var GetAssertReq = (getAssert) => {
2437
}
2538
throw new Error('No credential available to authenticate!');
2639
}).then(function(options) {
40+
if (window.conditionalUI) {
41+
options.mediation= 'conditional';
42+
}
2743
console.log(options)
2844
return navigator.credentials.get(options);
2945
}).then(function(assertion) {

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
setup(
66
name='django-passkeys',
7-
version='1.1.1',
7+
version='1.2.0',
88
description='A Django Authentication Backend for Passkeys',
99
long_description=open("README.md").read(),
1010
long_description_content_type="text/markdown",

0 commit comments

Comments
 (0)