303 lines
12 KiB
JavaScript
303 lines
12 KiB
JavaScript
const login_messages = document.getElementById('login-messages-inpt');
|
|
const otp_section = document.getElementById('otp-section');
|
|
const input_password = document.getElementById('login-password-inpt');
|
|
const input_repeat_password = document.getElementById('login-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('login-totp-url').value;
|
|
if (otp_url && otp_url !== '') {
|
|
const otp_message = document.getElementById('totp-message');
|
|
const url = new URL(otp_url);
|
|
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_role_chips = (elem) => {
|
|
const arr_items = elem.value == '' ? [] : elem.value.split(',');
|
|
const roles_chips = document.getElementById('roles-chips');
|
|
if (roles_chips) {
|
|
roles_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);
|
|
chip.innerHTML = `${name} <button type="button" class="inline-flex items-center p-0.5 ml-2 text-sm text-blue-400 bg-transparent rounded-sm hover:bg-blue-200 hover:text-blue-900 dark:hover:bg-blue-800 dark:hover:text-blue-300" data-dismiss-target="#badge-${name}" aria-label="Remove">
|
|
<svg aria-hidden="true" class="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
|
|
<span class="sr-only">Remove role</span></button> `;
|
|
roles_chips.append(chip);
|
|
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_role_chips(elem);
|
|
};
|
|
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');
|
|
}
|
|
};
|
|
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('login-totp-code').value || '';
|
|
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','<br>') || '',
|
|
warning: arr_text[2] || '',
|
|
};
|
|
} else {
|
|
return '';
|
|
}
|
|
} else {
|
|
return `Enter a valid value for ${name}`;
|
|
}
|
|
}
|
|
};
|
|
const log_in = async () => {
|
|
const elem_name = document.getElementById('login-name-inpt');
|
|
login_messages.innerHTML='';
|
|
if (elem_name.value == '') {
|
|
login_messages.innerHTML='Enter a name';
|
|
return;
|
|
}
|
|
if (! await set_name(elem_name)) { return; }
|
|
const name = elem_name.value;
|
|
const elem_password = document.getElementById('login-password-inpt');
|
|
if (elem_password.value == '') {
|
|
login_messages.innerHTML='Please include a password';
|
|
return;
|
|
}
|
|
if (!set_password(elem_password)) { return; }
|
|
const password = elem_password.value;
|
|
const otp_code = document.getElementById('login-totp-code').value || '';
|
|
const otp_url = document.getElementById('login-totp-url').value || ''
|
|
const otp_auth = document.getElementById('login-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 roles = document.getElementById('login-roles-inpt').value;
|
|
const fullname= document.getElementById('login-fullname-inpt').value;
|
|
const description = document.getElementById('login-description-inpt').value;
|
|
const elem_email = document.getElementById('login-email-inpt');
|
|
if (! await set_email(elem_email)) { return; }
|
|
const email = elem_email.value;
|
|
const theme = document.getElementById('theme-select').value;
|
|
const 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: '0',
|
|
name,
|
|
fullname,
|
|
description,
|
|
email,
|
|
password,
|
|
otp_code,
|
|
otp_url,
|
|
otp_auth,
|
|
roles,
|
|
items
|
|
//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('opt-code-text')
|
|
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);
|
|
});
|
|
}
|
|
}); |