Files
dockerStuff/config/tandoor/staticfiles/mfa/js/webauthn.88878ff60271.js
2025-11-16 21:46:46 +00:00

109 lines
3.4 KiB
JavaScript

(function () {
const allauth = window.allauth = window.allauth || {}
const webauthnJSON = window.webauthnJSON
function dispatchError (exception) {
const event = new CustomEvent('allauth.error', { detail: { tags: ['mfa', 'webauthn'], exception }, cancelable: true })
document.dispatchEvent(event)
if (!event.defaultPrevented) {
console.error(exception)
}
}
async function createCredentials (credentials, passwordless) {
credentials = JSON.parse(JSON.stringify(credentials))
const sel = credentials.publicKey.authenticatorSelection
if (passwordless != null) {
sel.residentKey = passwordless ? 'required' : 'discouraged'
sel.requireResidentKey = passwordless
sel.userVerification = passwordless ? 'required' : 'discouraged'
}
return await webauthnJSON.create(credentials)
}
function signupForm (o) {
const signupBtn = document.getElementById(o.ids.signup)
return addOrSignupForm(o, signupBtn, null)
}
function addForm (o) {
const addBtn = document.getElementById(o.ids.add)
const passwordlessCb = o.ids.passwordless ? document.getElementById(o.ids.passwordless) : null
const passwordlessFn = () => passwordlessCb ? passwordlessCb.checked : false
return addOrSignupForm(o, addBtn, passwordlessFn)
}
function getData (o) {
if (typeof o.ids.data !== 'undefined') {
return JSON.parse(document.getElementById(o.ids.data).textContent)
}
return o.data
}
function addOrSignupForm (o, actionBtn, passwordlessFn) {
const credentialInput = document.getElementById(o.ids.credential)
const form = credentialInput.closest('form')
actionBtn.addEventListener('click', async function () {
const passwordless = passwordlessFn ? passwordlessFn() : undefined
try {
const credential = await createCredentials(getData(o).creation_options, passwordless)
credentialInput.value = JSON.stringify(credential)
form.submit()
} catch (e) {
dispatchError(e)
}
})
}
function loginForm (o) {
const loginBtn = document.getElementById(o.ids.login)
const form = loginBtn.form
const credentialInput = document.getElementById(o.ids.credential)
loginBtn.addEventListener('click', async function (e) {
e.preventDefault()
try {
const response = await fetch(form.action, {
method: 'GET',
headers: {
Accept: 'application/json'
}
})
if (!response.ok) {
throw new Error('Unable to fetch passkey data from server.')
}
const data = await response.json()
const credential = await webauthnJSON.get(data.request_options)
credentialInput.value = JSON.stringify(credential)
form.submit()
} catch (e) {
dispatchError(e)
}
})
}
function authenticateForm (o) {
const authenticateBtn = document.getElementById(o.ids.authenticate)
const credentialInput = document.getElementById(o.ids.credential)
const form = credentialInput.closest('form')
authenticateBtn.addEventListener('click', async function (e) {
e.preventDefault()
try {
const credential = await webauthnJSON.get(getData(o).request_options)
credentialInput.value = JSON.stringify(credential)
form.submit()
} catch (e) {
dispatchError(e)
}
})
}
allauth.webauthn = {
forms: {
addForm,
authenticateForm,
loginForm,
signupForm
}
}
})()