const login_messages = document.getElementById('user-messages-inpt'); const otp_section = document.getElementById('otp-section'); const input_password = document.getElementById('user-password-inpt'); const input_repeat_password = document.getElementById('user-repeat-password-inpt'); const password_secure_bar = document.getElementById('password-secure-bar'); const password_secure_val = document.getElementById('password-secure-val'); const password_suggestions = document.getElementById('password-suggestions'); const password_warning = document.getElementById('password-warning'); const password_error = document.getElementById('password-error'); const get_otp_info = () => { const otp_url = document.getElementById('user-totp-url'); if (otp_url && otp_url.value !== '') { const otp_message = document.getElementById('totp-message'); const url = new URL(otp_url.value); if (url && url.searchParams) { let algo=''; let digits=''; if (totp_algorithm) { algo = totp_algorithm; } else { algo = url.searchParams.get('algorithm') || ''; } if (algo !== '') { algo = `Algorithm: ${algo} | `; } if (totp_digits) { digits = totp_digits || 0; } if (digits > 0) { digits = `| Digits: ${digits}`; } const issuer = `Issuer: ${url.searchParams.get('issuer') || ''}`; otp_message.innerHTML = ` ${algo} ${issuer} ${digits}`; } } } const check_value = async (name,value,elem) => { if (login_messages.innerHTML !== '') { login_messages.innerHTML=''; } const elem_error = document.getElementById(`${name}-error`); let res = await check_item(name,value); if (elem_error) { elem_error.innerHTML = res} if (res !== '') { elem.focus(); return false; } return true; }; const set_name = async (elem) => { if (elem.value === ' ' ) { login_messages.innerHTML='Please include a valid name'; return false; } return await check_value('name',elem.value,elem); }; const set_email = async (elem) => { if (elem.value === '' || !elem.value.includes('@')) { login_messages.innerHTML='Please include a valid email'; return false; } return await check_value('email',elem.value,elem); }; const set_totp = (elem) => { if (login_messages.innerHTML !== '') { login_messages.innerHTML=''; } }; const make_chips = (elem, keys) => { const arr_items = elem.value === '' ? [] : elem.value.split(','); const elem_chips = document.getElementById(`${keys}-chips`); if (elem_chips) { elem_chips.innerHTML=''; if (arr_items.length === 0) { return; } arr_items.forEach(name => { if (name.replaceAll(' ','') !== '') { const chip = document.createElement("span"); chip.id = `badge-${name}`; const arr_classes = "inline-flex items-center px-2 py-1 mr-2 text-sm font-medium text-blue-800 bg-blue-100 rounded dark:bg-blue-900 dark:text-blue-300".split(" "); chip.classList.add(...arr_classes); if (elem.disabled) { chip.innerHTML = `${name}`; } else { chip.innerHTML = `${name} `; } elem_chips.append(chip); if (!elem.disabled) { document.getElementById(`badge-${name}`).addEventListener('click', (ev) => { ev.preventDefault(); chip.remove(); elem.value = arr_items.filter(it => it !== name).join(','); }); } } }); } }; const set_role = (elem) => { if (login_messages.innerHTML !== '') { login_messages.innerHTML=''; } make_chips(elem, 'role'); }; const set_openids = (elem) => { if (login_messages.innerHTML !== '') { login_messages.innerHTML = ''; } make_chips(elem, 'openids'); }; const set_items = (elem) => { if (login_messages.innerHTML !== '') { login_messages.innerHTML=''; } }; const clean_password_messages = () => { if (password_secure_bar) { password_secure_bar.style.width = '0%'; } if (password_secure_val) { password_secure_val.innerHTML=0; } if (password_suggestions) { password_suggestions.innerHTML=''; } if (password_warning) { password_warning.innerHTML=''; } if (password_error) { password_error.innerHTML=''; } }; const set_password = async (elem) => { if (login_messages.innerHTML !== '') { login_messages.innerHTML=''; } clean_password_messages(); const feedback = await check_item('password',elem.value); if (password_secure_bar) { password_secure_bar.style.width = `${parseInt(feedback.score)*10}%`; } if (password_secure_val) { password_secure_val.innerHTML=feedback.score; } if (password_suggestions) { password_suggestions.innerHTML=feedback.suggestions; } if (password_warning) { password_warning.innerHTML=feedback.warning; } if (PASSWORD_SCORE && feedback.score < PASSWORD_SCORE) { elem.focus(); if (password_error) { password_error.innerHTML = `Password under score value: ${PASSWORD_SCORE}`; } return false; } if (input_password.value !== input_repeat_password.value) { login_messages.innerHTML = 'Password and repetition not mactch'; elem.focus(); return false; } return true; }; const change_use_totp = (elem) => { if (otp_section) { otp_section.classList.toggle('hidden'); } if (!elem.checked) { reset_totp(true); } else { const otp_auth = document.getElementById('user-totp-inpt'); const otp_code = document.getElementById('user-totp-code') if (otp_auth && otp_code && otp_code.value !== 0 ) { otp_auth.parentElement.classList.remove('hidden'); } } }; const reset_totp = (hide_parent) => { const otp_auth = document.getElementById('user-totp-inpt'); const otp_code = document.getElementById('user-totp-code'); if (otp_code) { otp_code.value='' } const otp_text = document.getElementById('otp-code-text'); if (otp_text) { otp_text.innerHTML='' } const otp_qr = document.getElementById('otp-code-qr'); if (otp_qr) { otp_qr.innerHTML='' } const copy_code = document.getElementById('copy-code'); const totp_message = document.getElementById('totp-message'); if (totp_message) { totp_message.innerHTML=''} const totp_recovery_message = document.getElementById('totp-recovery-message'); if (totp_recovery_message) { totp_recovery_message.classList.remove('hidden')} if (copy_code) { copy_code.classList.add('hidden') } if (otp_auth) { otp_auth.value = ''; if (hide_parent) { otp_auth.parentElement.classList.add('hidden') } } }; const on_reset_totp = (elem) => { if (elem.checked) { reset_totp(false); } }; const set_theme = (elem) => { if (settings && settings.elements) { const sel_theme = elem.value; const element = document.getElementsByTagName('html')[0]; const curr_theme = element.classList.contains('dark') ? 'dark': 'light'; if (curr_theme !== sel_theme) { if (sel_theme !== 'dark' && element.classList.contains('dark')) { element.classList.remove('dark'); } else { element.classList.add('dark'); } } } }; const copy_otp_code = (elem) => { const content = document.getElementById('user-totp-code').value || ''; if (content === '') { return } const toast_target = document.getElementById('toast-copy-totp-code'); navigator.clipboard.writeText(content).then( () => { if (toast_target) { utils.css('show', toast_target); setTimeout(() => { utils.css('hide', toast_target); }, settings.toast_copy_timeout); } }, ); }; const check_item = async (name, value) => { if (CHECK_URL) { const data = { name, value }; const response = await fetch(CHECK_URL, { method: 'POST', body: JSON.stringify(data), headers: { 'Content-type': 'application/json; charset=UTF-8', } }); login_messages.innerHTML=''; if (response.ok && response.status === 200 ) { if (name === 'password') { const text = await response.text(); const arr_text = text.split('|'); return { score: arr_text[0] || 0, suggestions: arr_text[1].replace('\n','
') || '', warning: arr_text[2] || '', }; } else { return ''; } } else { return `Enter a valid value for ${name}`; } } }; const log_in = async () => { login_messages.innerHTML=''; const elem_name = document.getElementById('user-name-inpt'); if (elem_name) { if (elem_name.value === '') { login_messages.innerHTML='Enter a name'; return; } const data_name = elem_name.dataset.val; if (data_name !== elem_name.value) { if (! await set_name(elem_name)) { return; } } } const name = elem_name ? elem_name.value : ''; const elem_password = document.getElementById('user-password-inpt'); if (elem_password) { if (elem_password.value === '') { login_messages.innerHTML='Please include a password'; return; } if (!set_password(elem_password)) { return; } } const password = elem_password ? elem_password.value : ''; let otp_code = ''; let otp_url = ''; let otp_auth = ''; const elem_otp_code = document.getElementById('user-totp-code'); if (elem_otp_code) { otp_code = elem_otp_code.value; otp_url = document.getElementById('user-totp-url').value || '' otp_auth = document.getElementById('user-totp-inpt').value || ''; if (otp_code !== '') { if (otp_auth === '' && totp_mode === "mandatory") { login_messages.innerHTML='Please enter a valid TOTP code'; return; } if (totp_mode === 'mandatory' || document.getElementById('use-totp').checked) { const numbers = /^[0-9]+$/; if(! otp_auth.match(numbers) || otp_auth.length !== totp_digits ) { login_messages.innerHTML='Please enter a valid TOTP code'; return; } } } } const elem_roles = document.getElementById('user-roles-inpt'); var roles = ''; if (elem_roles) { roles = elem_roles.value; } const elem_openids = document.getElementById('user-openids-inpt'); var openids = ''; if (elem_openids) { openids = elem_openids.value; } const elem_fullname= document.getElementById('user-fullname-inpt'); var fullname = ''; if (elem_fullname) { fullname = elem_fullname.value; } const elem_description = document.getElementById('user-description-inpt'); var description=''; if (elem_description) { description = elem_description.value; } const elem_email = document.getElementById('user-email-inpt'); if (elem_email) { const data_email = elem_email.dataset.val; if (data_email !== elem_email.value) { if (! await set_email(elem_email)) { return; } } } const email = elem_email ? elem_email.value : ''; const elem_theme = document.getElementById('theme-select'); var theme=''; var items={}; if (elem_theme){ theme= elem_theme.value; items = {'theme': theme }; } if (INVITE_KEY && INVITE_KEY !== '') { items.invite_key = INVITE_KEY; } if (INVITE_ID && INVITE_ID !== '') { items.invite_id = INVITE_ID; } const data = { id: id_user ? id_user : '0', name, fullname, description, email, password, otp_code, otp_url, otp_auth, roles, items, openids, //timestamp: new Date().toLocaleString(), }; const response = await fetch(SIGNIN_URL, { method: 'POST', body: JSON.stringify(data), headers: { 'Content-type': 'application/json; charset=UTF-8', // 'cookie': document.cookie, } }); if (response.ok && response.status === 200 ) { location.href='/'; } else { login_messages.innerHTML='Signin response was not OK'; // throw new Error('Signin response was not OK'); return false; } }; window.addEventListener('load', () => { get_otp_info(); const show_password = document.getElementById('show-password'); const show_repeat_password = document.getElementById('show-repeat-password'); const otp_code_text = document.getElementById('otp-code-text') const section_title = document.getElementById('section-title') const back_btn = document.getElementById('back-btn') const user_roles = document.getElementById('user-roles-inpt'); const user_openids = document.getElementById('user-openids-inpt'); if (show_password) { show_password.addEventListener('click', (ev) => { ev.preventDefault(); [...show_password.children].forEach(it => { it.classList.toggle('hidden'); }); if (input_password.type === 'password') { input_password.type = 'text'; } else { input_password.type = 'password'; } }); } if (show_repeat_password) { show_repeat_password.addEventListener('click', (ev) => { ev.preventDefault(); [...show_repeat_password.children].forEach(it => { it.classList.toggle('hidden'); }); if (input_repeat_password.type === 'password') { input_repeat_password.type = 'text'; } else { input_repeat_password.type = 'password'; } }); } if (otp_code_text) { otp_code_text.addEventListener('click', (ev) => { ev.preventDefault(); copy_otp_code(ev); }); } if (back_btn && BACK_URL) { back_btn.addEventListener('click', (ev) => { ev.preventDefault(); location.href=BACK_URL; }); } if (section_title && TITLE_URL) { section_title.addEventListener('click', (ev) => { ev.preventDefault(); location.href=TITLE_URL; }); } if (user_roles) { make_chips(user_roles, 'roles'); } if (user_openids) { make_chips(user_openids, 'openids'); } });