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',