').append(c,d,e),g=a('
').addClass(this.$element.prop("checked")?this._onstyle:this._offstyle+" off").addClass(b).addClass(this.options.style);this.$element.wrap(g),a.extend(this,{$toggle:this.$element.parent(),$toggleOn:c,$toggleOff:d,$toggleGroup:f}),this.$toggle.append(f);var h=this.options.width||Math.max(c.outerWidth(),d.outerWidth())+e.outerWidth()/2,i=this.options.height||Math.max(c.outerHeight(),d.outerHeight());c.addClass("toggle-on"),d.addClass("toggle-off"),this.$toggle.css({width:h,height:i}),this.options.height&&(c.css("line-height",c.height()+"px"),d.css("line-height",d.height()+"px")),this.update(!0),this.trigger(!0)},c.prototype.toggle=function(){this.$element.prop("checked")?this.off():this.on()},c.prototype.on=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._offstyle+" off").addClass(this._onstyle),this.$element.prop("checked",!0),void(a||this.trigger()))},c.prototype.off=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._onstyle).addClass(this._offstyle+" off"),this.$element.prop("checked",!1),void(a||this.trigger()))},c.prototype.enable=function(){this.$toggle.removeAttr("disabled"),this.$element.prop("disabled",!1)},c.prototype.disable=function(){this.$toggle.attr("disabled","disabled"),this.$element.prop("disabled",!0)},c.prototype.update=function(a){this.$element.prop("disabled")?this.disable():this.enable(),this.$element.prop("checked")?this.on(a):this.off(a)},c.prototype.trigger=function(b){this.$element.off("change.bs.toggle"),b||this.$element.change(),this.$element.on("change.bs.toggle",a.proxy(function(){this.update()},this))},c.prototype.destroy=function(){this.$element.off("change.bs.toggle"),this.$toggleGroup.remove(),this.$element.removeData("bs.toggle"),this.$element.unwrap()};var d=a.fn.bootstrapToggle;a.fn.bootstrapToggle=b,a.fn.bootstrapToggle.Constructor=c,a.fn.toggle.noConflict=function(){return a.fn.bootstrapToggle=d,this},a(function(){a("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle()}),a(document).on("click.bs.toggle","div[data-toggle^=toggle]",function(b){var c=a(this).find("input[type=checkbox]");c.bootstrapToggle("toggle"),b.preventDefault()})}(jQuery);
-//# sourceMappingURL=bootstrap-toggle.min.js.map
\ No newline at end of file
+/* Copyright Notice
+ * bootstrap5-toggle v5.0.4
+ * https://palcarazm.github.io/bootstrap5-toggle/
+ * @author 2011-2014 Min Hur (https://github.com/minhur)
+ * @author 2018-2019 Brent Ely (https://github.com/gitbrent)
+ * @author 2022 Pablo Alcaraz MartÃnez (https://github.com/palcarazm)
+ * @funding GitHub Sponsors
+ * @see https://github.com/sponsors/palcarazm
+ * @license MIT
+ * @see https://github.com/palcarazm/bootstrap5-toggle/blob/master/LICENSE
+ */
+
+"use strict";!function(){class s{constructor(e,t){const i="BOOTSTRAP TOGGLE DEPRECATION CHECK -- a0Jhux0QySypjjs4tLtEo8xT2kx0AbYaq9K6mgNjWSs0HF0L8T8J0M0o3Kr7zkm7 --",s="attribute",n="option",l=function(e,t,i){console.warn(`Bootstrap Toggle deprecation warning: Using ${t} ${e} is deprected. Use ${i} instead.`)},o="On",a="primary",h=null,d=null,r="Off",m="secondary",g=null,b=null,c="",u="",f=null,p=null,v=0,A=!1,y=null;t=t||{},this.element=e,this.options={onlabel:this.element.getAttribute("data-onlabel")||t.onlabel||i||o,onstyle:this.element.getAttribute("data-onstyle")||t.onstyle||a,onvalue:this.element.getAttribute("value")||this.element.getAttribute("data-onvalue")||t.onvalue||h,ontitle:this.element.getAttribute("data-ontitle")||t.ontitle||this.element.getAttribute("title")||d,offlabel:this.element.getAttribute("data-offlabel")||t.offlabel||i||r,offstyle:this.element.getAttribute("data-offstyle")||t.offstyle||m,offvalue:this.element.getAttribute("data-offvalue")||t.offvalue||g,offtitle:this.element.getAttribute("data-offtitle")||t.offtitle||this.element.getAttribute("title")||b,size:this.element.getAttribute("data-size")||t.size||c,style:this.element.getAttribute("data-style")||t.style||u,width:this.element.getAttribute("data-width")||t.width||f,height:this.element.getAttribute("data-height")||t.height||p,tabindex:this.element.getAttribute("tabindex")||t.tabindex||v,tristate:this.element.hasAttribute("tristate")||t.tristate||A,name:this.element.getAttribute("name")||t.name||y},this.options.onlabel===i&&(this.element.getAttribute("data-on")?(l(s,"data-on","data-onlabel"),this.options.onlabel=this.element.getAttribute("data-on")):t.on?(l(n,"on","onlabel"),this.options.onlabel=t.on):this.options.onlabel=o),this.options.offlabel===i&&(this.element.getAttribute("data-off")?(l(s,"data-off","data-offlabel"),this.options.offlabel=this.element.getAttribute("data-off")):t.off?(l(n,"off","offlabel"),this.options.offlabel=t.off):this.options.offlabel=r),this.render()}render(){function e(e){var t=window.getComputedStyle(e),e=e.offsetHeight,i=parseFloat(t.borderTopWidth);return e-parseFloat(t.borderBottomWidth)-i-parseFloat(t.paddingTop)-parseFloat(t.paddingBottom)}let t;switch(this.options.size){case"large":case"lg":t="btn-lg";break;case"small":case"sm":t="btn-sm";break;case"mini":case"xs":t="btn-xs";break;default:t=""}var i=document.createElement("span"),s=(i.setAttribute("class","btn btn-"+this.options.onstyle+" "+t),i.innerHTML=this.options.onlabel,this.options.ontitle&&i.setAttribute("title",this.options.ontitle),document.createElement("span")),n=(s.setAttribute("class","btn btn-"+this.options.offstyle+" "+t),s.innerHTML=this.options.offlabel,this.options.offtitle&&s.setAttribute("title",this.options.offtitle),document.createElement("span")),l=(n.setAttribute("class","toggle-handle btn "+t),document.createElement("div"));l.setAttribute("class","toggle-group"),l.appendChild(i),l.appendChild(s),l.appendChild(n);let o=document.createElement("div"),a=(o.setAttribute("class","toggle btn"),o.classList.add(this.element.checked?"btn-"+this.options.onstyle:"btn-"+this.options.offstyle),o.setAttribute("tabindex",this.options.tabindex),this.element.checked||o.classList.add("off"),this.options.size&&o.classList.add(t),this.options.style&&this.options.style.split(" ").forEach(e=>{o.classList.add(e)}),(this.element.disabled||this.element.readOnly)&&(o.classList.add("disabled"),o.setAttribute("disabled","disabled")),this.options.onvalue&&this.element.setAttribute("value",this.options.onvalue),null);this.options.offvalue&&((a=this.element.cloneNode()).setAttribute("value",this.options.offvalue),a.setAttribute("data-toggle","invert-toggle"),a.removeAttribute("id"),a.checked=!this.element.checked),this.element.parentElement.insertBefore(o,this.element),o.appendChild(this.element),a&&o.appendChild(a),o.appendChild(l),o.style.width=(this.options.width||Math.max(i.getBoundingClientRect().width,s.getBoundingClientRect().width)+n.getBoundingClientRect().width/2)+"px",o.style.height=(this.options.height||Math.max(i.getBoundingClientRect().height,s.getBoundingClientRect().height))+"px",i.classList.add("toggle-on"),s.classList.add("toggle-off"),this.options.height&&(i.style.lineHeight=e(i)+"px",s.style.lineHeight=e(s)+"px"),o.addEventListener("touchstart",e=>{this.#toggleActionPerformed(e)}),o.addEventListener("click",e=>{this.#toggleActionPerformed(e)}),o.addEventListener("keypress",e=>{" "==e.key&&this.#toggleActionPerformed(e)}),this.element.id&&document.querySelectorAll('label[for="'+this.element.id+'"]').forEach(e=>{e.addEventListener("touchstart",e=>{this.toggle(),o.focus()}),e.addEventListener("click",e=>{this.toggle(),o.focus()})}),this.ecmasToggle=o,this.invElement=a,this.element.bsToggle=this}#toggleActionPerformed(e){this.options.tristate?this.ecmasToggle.classList.contains("indeterminate")?(this.determinate(!0),this.toggle()):this.indeterminate():this.toggle(),e.preventDefault()}toggle(e=!1){this.element.checked?this.off(e):this.on(e)}on(e=!1){if(this.element.disabled||this.element.readOnly)return!1;this.ecmasToggle.classList.remove("btn-"+this.options.offstyle),this.ecmasToggle.classList.add("btn-"+this.options.onstyle),this.ecmasToggle.classList.remove("off"),this.element.checked=!0,this.invElement&&(this.invElement.checked=!1),e||this.trigger()}off(e=!1){if(this.element.disabled||this.element.readOnly)return!1;this.ecmasToggle.classList.remove("btn-"+this.options.onstyle),this.ecmasToggle.classList.add("btn-"+this.options.offstyle),this.ecmasToggle.classList.add("off"),this.element.checked=!1,this.invElement&&(this.invElement.checked=!0),e||this.trigger()}indeterminate(e=!1){if(!this.options.tristate||this.element.disabled||this.element.readOnly)return!1;this.ecmasToggle.classList.add("indeterminate"),this.element.indeterminate=!0,this.element.removeAttribute("name"),this.invElement&&(this.invElement.indeterminate=!0),this.invElement&&this.invElement.removeAttribute("name"),e||this.trigger()}determinate(e=!1){if(!this.options.tristate||this.element.disabled||this.element.readOnly)return!1;this.ecmasToggle.classList.remove("indeterminate"),this.element.indeterminate=!1,this.options.name&&this.element.setAttribute("name",this.options.name),this.invElement&&(this.invElement.indeterminate=!1),this.invElement&&this.options.name&&this.invElement.setAttribute("name",this.options.name),e||this.trigger()}enable(){this.ecmasToggle.classList.remove("disabled"),this.ecmasToggle.removeAttribute("disabled"),this.element.removeAttribute("disabled"),this.element.removeAttribute("readonly"),this.invElement&&(this.invElement.removeAttribute("disabled"),this.invElement.removeAttribute("readonly"))}disable(){this.ecmasToggle.classList.add("disabled"),this.ecmasToggle.setAttribute("disabled",""),this.element.setAttribute("disabled",""),this.element.removeAttribute("readonly"),this.invElement&&(this.invElement.setAttribute("disabled",""),this.invElement.removeAttribute("readonly"))}readonly(){this.ecmasToggle.classList.add("disabled"),this.ecmasToggle.setAttribute("disabled",""),this.element.removeAttribute("disabled"),this.element.setAttribute("readonly",""),this.invElement&&(this.invElement.removeAttribute("disabled"),this.invElement.setAttribute("readonly",""))}update(e){this.element.disabled?this.disable():this.element.readOnly?this.readonly():this.enable(),this.element.checked?this.on(e):this.off(e)}trigger(e){e||this.element.dispatchEvent(new Event("change",{bubbles:!0}))}destroy(){this.ecmasToggle.parentNode.insertBefore(this.element,this.ecmasToggle),this.ecmasToggle.parentNode.removeChild(this.ecmasToggle),delete this.element.bsToggle,delete this.ecmasToggle}}Element.prototype.bootstrapToggle=function(e,t){var i=this.bsToggle||new s(this,e);e&&"string"==typeof e&&("toggle"==e.toLowerCase()?i.toggle(t):"on"==e.toLowerCase()?i.on(t):"off"==e.toLowerCase()?i.off(t):"indeterminate"==e.toLowerCase()?i.indeterminate(t):"determinate"==e.toLowerCase()?i.determinate(t):"enable"==e.toLowerCase()?i.enable():"disable"==e.toLowerCase()?i.disable():"readonly"==e.toLowerCase()?i.readonly():"destroy"==e.toLowerCase()&&i.destroy())},"undefined"!=typeof window&&(window.onload=function(){document.querySelectorAll('input[type=checkbox][data-toggle="toggle"]').forEach(function(e){e.bootstrapToggle()})}),"undefined"!=typeof module&&module.exports&&(module.exports=s)}();
\ No newline at end of file
diff --git a/passkeys/templates/check_passkeys.js b/passkeys/templates/passkeys/check_passkeys.js
similarity index 100%
rename from passkeys/templates/check_passkeys.js
rename to passkeys/templates/passkeys/check_passkeys.js
diff --git a/passkeys/templates/modal.html b/passkeys/templates/passkeys/modal.html
similarity index 100%
rename from passkeys/templates/modal.html
rename to passkeys/templates/passkeys/modal.html
diff --git a/passkeys/templates/PassKeys.html b/passkeys/templates/passkeys/passkeys.html
similarity index 51%
rename from passkeys/templates/PassKeys.html
rename to passkeys/templates/passkeys/passkeys.html
index 5feddf4..9ddd1f6 100644
--- a/passkeys/templates/PassKeys.html
+++ b/passkeys/templates/passkeys/passkeys.html
@@ -1,7 +1,12 @@
-{% extends "PassKeys_base.html" %}
+{% extends "passkeys/passkeys_base.html" %}
{% load static %}
{% block head %}
{{block.super}}
+
@@ -148,5 +164,5 @@
{% endif %}
- {% include "modal.html" %}
+ {% include "passkeys/modal.html" %}
{% endblock %}
diff --git a/passkeys/templates/passkeys.js b/passkeys/templates/passkeys/passkeys.js
similarity index 87%
rename from passkeys/templates/passkeys.js
rename to passkeys/templates/passkeys/passkeys.js
index d3c855f..cb0b45b 100644
--- a/passkeys/templates/passkeys.js
+++ b/passkeys/templates/passkeys/passkeys.js
@@ -49,13 +49,13 @@ var GetAssertReq = (getAssert) => {
console.log(options)
return navigator.credentials.get(options);
}).then(function(assertion) {
- pk = $("#passkeys")
+ pk = document.getElementById("passkeys");
if (pk.length == 0)
{
console.error("Did you add the 'passkeys' hidden input field")
return
}
- pk.val(JSON.stringify(publicKeyCredentialToJSON(assertion)));
+ pk.value = JSON.stringify(publicKeyCredentialToJSON(assertion));
x= document.getElementById(window.loginForm)
if (x === null || x === undefined)
{
@@ -65,11 +65,13 @@ var GetAssertReq = (getAssert) => {
x.submit()
});
- $(document).ready(function () {
- if (location.protocol != 'https:') {
- console.error("Passkeys must work under secure context")
- }
- });
+
+ document.addEventListener("DOMContentLoaded", ()=>{
+ if (location.protocol != 'https:') {
+ console.error("Passkeys must work under secure context");
+ }
+ });
+
}
function authn(form)
{
diff --git a/passkeys/templates/PassKeys_base.html b/passkeys/templates/passkeys/passkeys_base.html
similarity index 100%
rename from passkeys/templates/PassKeys_base.html
rename to passkeys/templates/passkeys/passkeys_base.html
diff --git a/passkeys/views.py b/passkeys/views.py
index d3d06f9..fe63888 100644
--- a/passkeys/views.py
+++ b/passkeys/views.py
@@ -1,26 +1,33 @@
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from django.shortcuts import render
+from django.views.decorators.http import require_http_methods
from .models import UserPasskey
@login_required
def index(request,enroll=False): # noqa
keys = UserPasskey.objects.filter(user=request.user) # pragma: no cover
- return render(request,'PassKeys.html',{"keys":keys,"enroll":enroll}) # pragma: no cover
-
+ return render(request,'passkeys/passkeys.html',{"keys":keys,"enroll":enroll}) # pragma: no cover
+@require_http_methods(["POST"])
@login_required
def delKey(request):
- key=UserPasskey.objects.get(id=request.GET["id"])
- if key.user.pk == request.user.pk:
+ id=request.POST.get("id")
+ if not id:
+ return HttpResponse("Error: You are missing a key", status=403)
+ key=UserPasskey.objects.get(id=id)
+ if key.user.pk == request.user.pk:
key.delete()
return HttpResponse("Deleted Successfully")
return HttpResponse("Error: You own this token so you can't delete it", status=403)
+@require_http_methods(["POST"])
@login_required
def toggleKey(request):
- id=request.GET["id"]
+ id=request.POST.get("id")
+ if not id:
+ return HttpResponse("Error: You are missing a key", status=403)
q=UserPasskey.objects.filter(user=request.user, id=id)
if q.count()==1:
key=q[0]