Skip to content

Commit ce411ed

Browse files
committed
Perform more advanced input and string sanitization and validation for performance and security
1 parent 9859a32 commit ce411ed

File tree

7 files changed

+115
-20
lines changed

7 files changed

+115
-20
lines changed

src/UI/UINotification.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function UINotification(options){
2525
let h = '';
2626
h += `<div id="ui-notification__${global_element_id}" class="notification antialiased animate__animated animate__fadeInRight animate__slow">`;
2727
h += `<img class="notification-close" src="${html_encode(window.icons['close.svg'])}">`;
28-
h += options.content;
28+
h += html_encode(options.content);
2929
h += `</div>`;
3030

3131
$('body').append(h);

src/UI/UIWindowChangePassword.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -88,21 +88,31 @@ async function UIWindowChangePassword(options){
8888
const new_password = $(el_window).find('.new-password').val();
8989
const confirm_new_password = $(el_window).find('.confirm-new-password').val();
9090

91-
let data;
91+
// hide success message
92+
$(el_window).find('.form-success-msg').hide();
9293

93-
if(current_password === '' || new_password === '' || confirm_new_password === ''){
94+
// check if all fields are filled
95+
if(!current_password || !new_password || !confirm_new_password){
9496
$(el_window).find('.form-error-msg').html('All fields are required.');
9597
$(el_window).find('.form-error-msg').fadeIn();
9698
return;
9799
}
100+
// check if new password and confirm new password are the same
98101
else if(new_password !== confirm_new_password){
99102
$(el_window).find('.form-error-msg').html(i18n('passwords_do_not_match'));
100103
$(el_window).find('.form-error-msg').fadeIn();
101104
return;
102105
}
103-
106+
// check password strength
107+
const pass_strength = check_password_strength(new_password);
108+
if(!pass_strength.overallPass){
109+
$(el_window).find('.form-error-msg').html(i18n('password_strength_error'));
110+
$(el_window).find('.form-error-msg').fadeIn();
111+
return;
112+
}
113+
104114
$(el_window).find('.form-error-msg').hide();
105-
115+
106116
$.ajax({
107117
url: api_origin + "/passwd",
108118
type: 'POST',

src/UI/UIWindowNewPassword.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ async function UIWindowNewPassword(options){
3030
h += `<div class="change-password" style="padding: 20px; border-bottom: 1px solid #ced7e1;">`;
3131
// error msg
3232
h += `<div class="form-error-msg"></div>`;
33-
// success msg
34-
h += `<div class="form-success-msg"></div>`;
3533
// new password
3634
h += `<div style="overflow: hidden; margin-top: 20px; margin-bottom: 20px;">`;
3735
h += `<label for="new-password-${internal_id}">${i18n('new_password')}</label>`;
@@ -84,7 +82,7 @@ async function UIWindowNewPassword(options){
8482
const new_password = $(el_window).find('.new-password').val();
8583
const confirm_new_password = $(el_window).find('.confirm-new-password').val();
8684

87-
if(new_password === '' || confirm_new_password === ''){
85+
if(!new_password || !confirm_new_password){
8886
$(el_window).find('.form-error-msg').html('All fields are required.');
8987
$(el_window).find('.form-error-msg').fadeIn();
9088
return;
@@ -94,6 +92,14 @@ async function UIWindowNewPassword(options){
9492
$(el_window).find('.form-error-msg').fadeIn();
9593
return;
9694
}
95+
96+
// check password strength
97+
const pass_strength = check_password_strength(new_password);
98+
if(!pass_strength.overallPass){
99+
$(el_window).find('.form-error-msg').html(i18n('password_strength_error'));
100+
$(el_window).find('.form-error-msg').fadeIn();
101+
return;
102+
}
97103

98104
$(el_window).find('.form-error-msg').hide();
99105

src/UI/UIWindowSignup.js

+37-6
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ function UIWindowSignup(options){
114114
'justify-content': 'center',
115115
'align-items': 'center',
116116
padding: '30px 10px 10px 10px',
117-
}
117+
}
118118
})
119119

120120
$(el_window).find('.login-c2a-clickable').on('click', async function(e){
@@ -132,17 +132,48 @@ function UIWindowSignup(options){
132132
})
133133

134134
$(el_window).find('.signup-btn').on('click', function(e){
135-
// todo do some basic validation client-side
136-
137135
//Username
138136
let username = $(el_window).find('.username').val();
137+
138+
if(!username){
139+
$(el_window).find('.signup-error-msg').html(i18n('username_required'));
140+
$(el_window).find('.signup-error-msg').fadeIn();
141+
return;
142+
}
139143

140144
//Email
141145
let email = $(el_window).find('.email').val();
142-
146+
147+
// must have an email
148+
if(!email){
149+
$(el_window).find('.signup-error-msg').html(i18n('email_required'));
150+
$(el_window).find('.signup-error-msg').fadeIn();
151+
return;
152+
}
153+
// must be a valid email
154+
else if(!is_email(email)){
155+
$(el_window).find('.signup-error-msg').html(i18n('email_invalid'));
156+
$(el_window).find('.signup-error-msg').fadeIn();
157+
return;
158+
}
159+
143160
//Password
144161
let password = $(el_window).find('.password').val();
145-
162+
163+
// must have a password
164+
if(!password){
165+
$(el_window).find('.signup-error-msg').html(i18n('password_required'));
166+
$(el_window).find('.signup-error-msg').fadeIn();
167+
return;
168+
}
169+
// check password strength
170+
const pass_strength = check_password_strength(password);
171+
if(!pass_strength.overallPass){
172+
$(el_window).find('.signup-error-msg').html(i18n('password_strength_error'));
173+
$(el_window).find('.signup-error-msg').fadeIn();
174+
return;
175+
}
176+
146177
//xyzname
147178
let p102xyzname = $(el_window).find('.p102xyzname').val();
148179

@@ -186,7 +217,7 @@ function UIWindowSignup(options){
186217
error: function (err){
187218
$(el_window).find('.signup-error-msg').html(err.responseText);
188219
$(el_window).find('.signup-error-msg').fadeIn();
189-
// re-enable 'Create Account' button
220+
// re-enable 'Create Account' button so user can try again
190221
$(el_window).find('.signup-btn').prop('disabled', false);
191222
}
192223
});

src/UI/UIWindowTaskManager.js

-4
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ const UIWindowTaskManager = async function UIWindowTaskManager () {
3434
body_css: {
3535
width: 'initial',
3636
padding: '20px',
37-
// 'background-color': `hsla(
38-
// var(--primary-hue),
39-
// calc(max(var(--primary-saturation) - 15%, 0%)),
40-
// calc(min(100%,var(--primary-lightness) + 20%)), .91)`,
4137
'background-color': `hsla(
4238
var(--primary-hue),
4339
var(--primary-saturation),

src/helpers.js

+50-2
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,8 @@ import UIWindowSaveAccount from './UI/UIWindowSaveAccount.js';
2727
import UIWindowCopyProgress from './UI/UIWindowCopyProgress.js';
2828
import UIWindowMoveProgress from './UI/UIWindowMoveProgress.js';
2929
import UIWindowNewFolderProgress from './UI/UIWindowNewFolderProgress.js';
30-
import UIWindowDownloadProgress from './UI/UIWindowDownloadProgress.js';
3130
import UIWindowUploadProgress from './UI/UIWindowUploadProgress.js';
3231
import UIWindowProgressEmptyTrash from './UI/UIWindowProgressEmptyTrash.js';
33-
import download from './helpers/download.js';
3432
import update_username_in_gui from './helpers/update_username_in_gui.js';
3533
import update_title_based_on_uploads from './helpers/update_title_based_on_uploads.js';
3634
import content_type_to_icon from './helpers/content_type_to_icon.js';
@@ -3497,3 +3495,53 @@ window.report_app_closed = (instance_id) => {
34973495

34983496
// TODO: Once other AppConnections exist, those will need notifying too.
34993497
};
3498+
3499+
window.check_password_strength = (password) => {
3500+
// Define criteria for password strength
3501+
const criteria = {
3502+
minLength: 8,
3503+
hasUpperCase: /[A-Z]/.test(password),
3504+
hasLowerCase: /[a-z]/.test(password),
3505+
hasNumber: /\d/.test(password),
3506+
hasSpecialChar: /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)
3507+
};
3508+
3509+
let overallPass = true;
3510+
3511+
// Initialize report object
3512+
let criteria_report = {
3513+
minLength: {
3514+
message: `Password must be at least ${criteria.minLength} characters long`,
3515+
pass: password.length >= criteria.minLength,
3516+
},
3517+
hasUpperCase: {
3518+
message: 'Password must contain at least one uppercase letter',
3519+
pass: criteria.hasUpperCase,
3520+
},
3521+
hasLowerCase: {
3522+
message: 'Password must contain at least one lowercase letter',
3523+
pass: criteria.hasLowerCase,
3524+
},
3525+
hasNumber: {
3526+
message: 'Password must contain at least one number',
3527+
pass: criteria.hasNumber,
3528+
},
3529+
hasSpecialChar: {
3530+
message: 'Password must contain at least one special character',
3531+
pass: criteria.hasSpecialChar,
3532+
},
3533+
};
3534+
3535+
// Check overall pass status and add messages
3536+
for (let criterion in criteria) {
3537+
if (!criteria_report[criterion].pass) {
3538+
overallPass = false;
3539+
break;
3540+
}
3541+
}
3542+
3543+
return {
3544+
overallPass: overallPass,
3545+
report: criteria_report,
3546+
};
3547+
}

src/i18n/translations/en.js

+4
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ const en = {
8888
email: "Email",
8989
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.",
9090
email_or_username: "Email or Username",
91+
email_required: 'Email is required.',
9192
empty_trash: 'Empty Trash',
9293
empty_trash_confirmation: `Are you sure you want to permanently delete the items in Trash?`,
9394
emptying_trash: 'Emptying Trash…',
@@ -148,6 +149,8 @@ const en = {
148149
oss_code_and_content: "Open Source Software and Content",
149150
password: "Password",
150151
password_changed: "Password changed.",
152+
password_required: 'Password is required.',
153+
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.",
151154
passwords_do_not_match: '`New Password` and `Confirm New Password` do not match.',
152155
paste: 'Paste',
153156
paste_into_folder: "Paste Into Folder",
@@ -238,6 +241,7 @@ const en = {
238241
usage: 'Usage',
239242
username: "Username",
240243
username_changed: 'Username updated successfully.',
244+
username_required: 'Username is required.',
241245
versions: "Versions",
242246
visibility: 'Visibility',
243247
yes: 'Yes',

0 commit comments

Comments
 (0)