github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/assets/scripts/twofactor.js (about)

     1  ;(function (w, d) {
     2    if (!w.fetch || !w.Headers) return
     3  
     4    const twofaForm = d.getElementById('two-factor-form')
     5    const twofaField = d.getElementById('two-factor-field')
     6    const redirectInput = d.getElementById('redirect')
     7    const stateInput = d.getElementById('state')
     8    const confirmInput = d.getElementById('confirm')
     9    const clientIdInput = d.getElementById('client_id')
    10    const submitButton = d.getElementById('two-factor-submit')
    11    const passcodeInput = d.getElementById('two-factor-passcode')
    12    const tokenInput = d.getElementById('two-factor-token')
    13    const trustCheckbox = d.getElementById('two-factor-trust-device')
    14    const longRunCheckbox = d.getElementById('long-run-session')
    15  
    16    const storage = w.localStorage
    17  
    18    const onSubmitTwoFactorCode = function (event) {
    19      event.preventDefault()
    20      passcodeInput.setAttribute('disabled', true)
    21      submitButton.setAttribute('disabled', true)
    22  
    23      const longRun = longRunCheckbox && longRunCheckbox.checked ? '1' : '0'
    24      const passcode = passcodeInput.value
    25      const token = tokenInput.value
    26      const trustDevice = trustCheckbox && trustCheckbox.checked ? '1' : '0'
    27      const redirect = redirectInput.value + w.location.hash
    28  
    29      const data = new URLSearchParams()
    30      data.append('two-factor-passcode', passcode)
    31      data.append('long-run-session', longRun)
    32      data.append('two-factor-token', token)
    33      data.append('two-factor-generate-trusted-device-token', trustDevice)
    34      data.append('redirect', redirect)
    35  
    36      // When 2FA is checked for moving a Cozy to this instance
    37      if (stateInput) {
    38        data.append('state', stateInput.value)
    39      }
    40      if (clientIdInput) {
    41        data.append('client_id', clientIdInput.value)
    42      }
    43  
    44      // When 2FA is checked for confirming authentication
    45      if (confirmInput && confirmInput.value === 'true') {
    46        data.append('confirm', true)
    47      }
    48  
    49      const headers = new Headers()
    50      headers.append('Content-Type', 'application/x-www-form-urlencoded')
    51      headers.append('Accept', 'application/json')
    52      return fetch('/auth/twofactor', {
    53        method: 'POST',
    54        headers: headers,
    55        body: data,
    56        credentials: 'same-origin',
    57      })
    58        .then((response) => {
    59          return response.json().then(function (body) {
    60            if (response.status < 400) {
    61              if (
    62                storage &&
    63                typeof body.two_factor_trusted_device_token == 'string'
    64              ) {
    65                storage.setItem(
    66                  'trusted-device-token',
    67                  body.two_factor_trusted_device_token,
    68                )
    69              }
    70              const tooltip = twofaField.querySelector('.invalid-tooltip')
    71              if (tooltip) {
    72                tooltip.classList.add('d-none')
    73              }
    74              submitButton.innerHTML = '<span class="icon icon-check"></span>'
    75              submitButton.classList.add('btn-done')
    76              w.location = body.redirect
    77            } else {
    78              w.showError(twofaField, body.error)
    79            }
    80          })
    81        })
    82        .catch((err) => w.showError(twofaField, err))
    83    }
    84  
    85    twofaForm.addEventListener('submit', onSubmitTwoFactorCode)
    86  })(window, document)