github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/assets/scripts/login.js (about) 1 ;(function (w, d) { 2 if (!w.fetch || !w.Headers) return 3 4 const loginForm = d.getElementById('login-form') 5 const passphraseInput = d.getElementById('password') 6 const submitButton = d.getElementById('login-submit') 7 const redirectInput = d.getElementById('redirect') 8 const csrfTokenInput = d.getElementById('csrf_token') 9 const stateInput = d.getElementById('state') 10 const clientIdInput = d.getElementById('client_id') 11 const loginField = d.getElementById('login-field') 12 const longRunCheckbox = d.getElementById('long-run-session') 13 const trustedTokenInput = d.getElementById('trusted-device-token') 14 const emailVerifiedCodeInput = d.getElementById('email_verified_code') 15 const magicCodeInput = d.getElementById('magic_code') 16 17 // Set the trusted device token from the localstorage in the form if it exists 18 try { 19 const storage = w.localStorage 20 const deviceToken = storage.getItem('trusted-device-token') || '' 21 trustedTokenInput.value = deviceToken 22 } catch (e) { 23 console.log(e) // do nothing 24 } 25 26 const onSubmitPassphrase = function (event) { 27 event.preventDefault() 28 passphraseInput.setAttribute('disabled', true) 29 30 const passphrase = passphraseInput.value 31 const longRun = longRunCheckbox && longRunCheckbox.checked ? '1' : '0' 32 const redirect = redirectInput && redirectInput.value + w.location.hash 33 34 let passPromise = Promise.resolve(passphrase) 35 const salt = loginForm.dataset.salt 36 const iterations = parseInt(loginForm.dataset.iterations, 10) 37 if (iterations > 0) { 38 passPromise = w.password 39 .hash(passphrase, salt, iterations) 40 .then(({ hashed }) => hashed) 41 } 42 43 passPromise 44 .then((pass) => { 45 const data = new URLSearchParams() 46 data.append('passphrase', pass) 47 data.append('trusted-device-token', trustedTokenInput.value) 48 data.append('long-run-session', longRun) 49 data.append('redirect', redirect) 50 data.append('csrf_token', csrfTokenInput.value) 51 52 if (emailVerifiedCodeInput) { 53 data.append('email_verified_code', emailVerifiedCodeInput.value) 54 } 55 56 // For the /auth/authorize/move && /auth/confirm pages 57 if (stateInput) { 58 data.append('state', stateInput.value) 59 } 60 if (clientIdInput) { 61 data.append('client_id', clientIdInput.value) 62 } 63 // For the /auth/magic_link page 64 if (magicCodeInput) { 65 data.append('magic_code', magicCodeInput.value) 66 } 67 68 const headers = new Headers() 69 headers.append('Content-Type', 'application/x-www-form-urlencoded') 70 headers.append('Accept', 'application/json') 71 return fetch(loginForm.action, { 72 method: 'POST', 73 headers: headers, 74 body: data, 75 credentials: 'same-origin', 76 }) 77 }) 78 .then((response) => { 79 return response.json().then((body) => { 80 if (response.status < 400) { 81 const tooltip = loginField.querySelector('.invalid-tooltip') 82 if (tooltip) { 83 tooltip.classList.add('d-none') 84 } 85 submitButton.innerHTML = '<span class="icon icon-check"></span>' 86 submitButton.classList.add('btn-done') 87 w.location = body.redirect 88 } else { 89 w.showError(loginField, body.error) 90 } 91 }) 92 }) 93 .catch((err) => w.showError(loginField, err)) 94 } 95 96 loginForm.addEventListener('submit', onSubmitPassphrase) 97 passphraseInput.focus() 98 submitButton.removeAttribute('disabled') 99 })(window, document)