diff --git a/src/UI/UINotification.js b/src/UI/UINotification.js index fbbc9f6c2..697d23e39 100644 --- a/src/UI/UINotification.js +++ b/src/UI/UINotification.js @@ -25,7 +25,7 @@ function UINotification(options){ let h = ''; h += `
`; h += ``; - h += options.content; + h += html_encode(options.content); h += `
`; $('body').append(h); diff --git a/src/UI/UIWindowChangePassword.js b/src/UI/UIWindowChangePassword.js index 10c334748..9383017f2 100644 --- a/src/UI/UIWindowChangePassword.js +++ b/src/UI/UIWindowChangePassword.js @@ -88,21 +88,31 @@ async function UIWindowChangePassword(options){ const new_password = $(el_window).find('.new-password').val(); const confirm_new_password = $(el_window).find('.confirm-new-password').val(); - let data; + // hide success message + $(el_window).find('.form-success-msg').hide(); - if(current_password === '' || new_password === '' || confirm_new_password === ''){ + // check if all fields are filled + if(!current_password || !new_password || !confirm_new_password){ $(el_window).find('.form-error-msg').html('All fields are required.'); $(el_window).find('.form-error-msg').fadeIn(); return; } + // check if new password and confirm new password are the same else if(new_password !== confirm_new_password){ $(el_window).find('.form-error-msg').html(i18n('passwords_do_not_match')); $(el_window).find('.form-error-msg').fadeIn(); return; } - + // check password strength + const pass_strength = check_password_strength(new_password); + if(!pass_strength.overallPass){ + $(el_window).find('.form-error-msg').html(i18n('password_strength_error')); + $(el_window).find('.form-error-msg').fadeIn(); + return; + } + $(el_window).find('.form-error-msg').hide(); - + $.ajax({ url: api_origin + "/passwd", type: 'POST', diff --git a/src/UI/UIWindowNewPassword.js b/src/UI/UIWindowNewPassword.js index 3467d2945..2fab5c06f 100644 --- a/src/UI/UIWindowNewPassword.js +++ b/src/UI/UIWindowNewPassword.js @@ -30,8 +30,6 @@ async function UIWindowNewPassword(options){ h += `
`; // error msg h += `
`; - // success msg - h += `
`; // new password h += `
`; h += ``; @@ -84,7 +82,7 @@ async function UIWindowNewPassword(options){ const new_password = $(el_window).find('.new-password').val(); const confirm_new_password = $(el_window).find('.confirm-new-password').val(); - if(new_password === '' || confirm_new_password === ''){ + if(!new_password || !confirm_new_password){ $(el_window).find('.form-error-msg').html('All fields are required.'); $(el_window).find('.form-error-msg').fadeIn(); return; @@ -94,6 +92,14 @@ async function UIWindowNewPassword(options){ $(el_window).find('.form-error-msg').fadeIn(); return; } + + // check password strength + const pass_strength = check_password_strength(new_password); + if(!pass_strength.overallPass){ + $(el_window).find('.form-error-msg').html(i18n('password_strength_error')); + $(el_window).find('.form-error-msg').fadeIn(); + return; + } $(el_window).find('.form-error-msg').hide(); diff --git a/src/UI/UIWindowSignup.js b/src/UI/UIWindowSignup.js index e3dbb2033..956a90e1e 100644 --- a/src/UI/UIWindowSignup.js +++ b/src/UI/UIWindowSignup.js @@ -114,7 +114,7 @@ function UIWindowSignup(options){ 'justify-content': 'center', 'align-items': 'center', padding: '30px 10px 10px 10px', - } + } }) $(el_window).find('.login-c2a-clickable').on('click', async function(e){ @@ -132,17 +132,48 @@ function UIWindowSignup(options){ }) $(el_window).find('.signup-btn').on('click', function(e){ - // todo do some basic validation client-side - //Username let username = $(el_window).find('.username').val(); + + if(!username){ + $(el_window).find('.signup-error-msg').html(i18n('username_required')); + $(el_window).find('.signup-error-msg').fadeIn(); + return; + } //Email let email = $(el_window).find('.email').val(); - + + // must have an email + if(!email){ + $(el_window).find('.signup-error-msg').html(i18n('email_required')); + $(el_window).find('.signup-error-msg').fadeIn(); + return; + } + // must be a valid email + else if(!is_email(email)){ + $(el_window).find('.signup-error-msg').html(i18n('email_invalid')); + $(el_window).find('.signup-error-msg').fadeIn(); + return; + } + //Password let password = $(el_window).find('.password').val(); - + + // must have a password + if(!password){ + $(el_window).find('.signup-error-msg').html(i18n('password_required')); + $(el_window).find('.signup-error-msg').fadeIn(); + return; + } + // check password strength + const pass_strength = check_password_strength(password); + if(!pass_strength.overallPass){ + $(el_window).find('.signup-error-msg').html(i18n('password_strength_error')); + $(el_window).find('.signup-error-msg').fadeIn(); + return; + } + //xyzname let p102xyzname = $(el_window).find('.p102xyzname').val(); @@ -186,7 +217,7 @@ function UIWindowSignup(options){ error: function (err){ $(el_window).find('.signup-error-msg').html(err.responseText); $(el_window).find('.signup-error-msg').fadeIn(); - // re-enable 'Create Account' button + // re-enable 'Create Account' button so user can try again $(el_window).find('.signup-btn').prop('disabled', false); } }); diff --git a/src/UI/UIWindowTaskManager.js b/src/UI/UIWindowTaskManager.js index 8c9a6322e..3b4ab3011 100644 --- a/src/UI/UIWindowTaskManager.js +++ b/src/UI/UIWindowTaskManager.js @@ -34,10 +34,6 @@ const UIWindowTaskManager = async function UIWindowTaskManager () { body_css: { width: 'initial', padding: '20px', - // 'background-color': `hsla( - // var(--primary-hue), - // calc(max(var(--primary-saturation) - 15%, 0%)), - // calc(min(100%,var(--primary-lightness) + 20%)), .91)`, 'background-color': `hsla( var(--primary-hue), var(--primary-saturation), diff --git a/src/helpers.js b/src/helpers.js index 5158fc0c5..467d896aa 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -27,10 +27,8 @@ import UIWindowSaveAccount from './UI/UIWindowSaveAccount.js'; import UIWindowCopyProgress from './UI/UIWindowCopyProgress.js'; import UIWindowMoveProgress from './UI/UIWindowMoveProgress.js'; import UIWindowNewFolderProgress from './UI/UIWindowNewFolderProgress.js'; -import UIWindowDownloadProgress from './UI/UIWindowDownloadProgress.js'; import UIWindowUploadProgress from './UI/UIWindowUploadProgress.js'; import UIWindowProgressEmptyTrash from './UI/UIWindowProgressEmptyTrash.js'; -import download from './helpers/download.js'; import update_username_in_gui from './helpers/update_username_in_gui.js'; import update_title_based_on_uploads from './helpers/update_title_based_on_uploads.js'; import content_type_to_icon from './helpers/content_type_to_icon.js'; @@ -3497,3 +3495,53 @@ window.report_app_closed = (instance_id) => { // TODO: Once other AppConnections exist, those will need notifying too. }; + +window.check_password_strength = (password) => { + // Define criteria for password strength + const criteria = { + minLength: 8, + hasUpperCase: /[A-Z]/.test(password), + hasLowerCase: /[a-z]/.test(password), + hasNumber: /\d/.test(password), + hasSpecialChar: /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password) + }; + + let overallPass = true; + + // Initialize report object + let criteria_report = { + minLength: { + message: `Password must be at least ${criteria.minLength} characters long`, + pass: password.length >= criteria.minLength, + }, + hasUpperCase: { + message: 'Password must contain at least one uppercase letter', + pass: criteria.hasUpperCase, + }, + hasLowerCase: { + message: 'Password must contain at least one lowercase letter', + pass: criteria.hasLowerCase, + }, + hasNumber: { + message: 'Password must contain at least one number', + pass: criteria.hasNumber, + }, + hasSpecialChar: { + message: 'Password must contain at least one special character', + pass: criteria.hasSpecialChar, + }, + }; + + // Check overall pass status and add messages + for (let criterion in criteria) { + if (!criteria_report[criterion].pass) { + overallPass = false; + break; + } + } + + return { + overallPass: overallPass, + report: criteria_report, + }; +} \ No newline at end of file diff --git a/src/i18n/translations/en.js b/src/i18n/translations/en.js index eab5afac7..9754e6158 100644 --- a/src/i18n/translations/en.js +++ b/src/i18n/translations/en.js @@ -88,6 +88,7 @@ const en = { email: "Email", email_change_confirmation_sent: "A confirmation email has been sent to your new email address. Please check your inbox and follow the instructions to complete the process.", email_or_username: "Email or Username", + email_required: 'Email is required.', empty_trash: 'Empty Trash', empty_trash_confirmation: `Are you sure you want to permanently delete the items in Trash?`, emptying_trash: 'Emptying Trash…', @@ -148,6 +149,8 @@ const en = { oss_code_and_content: "Open Source Software and Content", password: "Password", password_changed: "Password changed.", + password_required: 'Password is required.', + password_strength_error: "Password must be at least 8 characters long and contain at least one uppercase letter, one lowercase letter, one number, and one special character.", passwords_do_not_match: '`New Password` and `Confirm New Password` do not match.', paste: 'Paste', paste_into_folder: "Paste Into Folder", @@ -238,6 +241,7 @@ const en = { usage: 'Usage', username: "Username", username_changed: 'Username updated successfully.', + username_required: 'Username is required.', versions: "Versions", visibility: 'Visibility', yes: 'Yes',