Skip to content

Commit 06b8000

Browse files
Added User Input Validators
More functionality improvements in WebGUI code to have validators for the password & postponement days input text boxes.
1 parent b703403 commit 06b8000

File tree

2 files changed

+171
-78
lines changed

2 files changed

+171
-78
lines changed

MerlinAU.asp

Lines changed: 169 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -29,38 +29,159 @@
2929
<script language="JavaScript" type="text/javascript">
3030
3131
/**----------------------------**/
32-
/** Last Modified: 2025-Jan-11 **/
32+
/** Last Modified: 2025-Jan-13 **/
3333
/** Intended for 1.4.0 Release **/
3434
/**----------------------------**/
3535
36+
// Separate variables for server and AJAX settings //
37+
var advanced_settings = {};
38+
var custom_settings = {};
39+
var server_custom_settings = {};
40+
var ajax_custom_settings = {};
41+
3642
// Define color formatting //
37-
var CYANct = "<span style='color:cyan;'>";
38-
var REDct = "<span style='color:red;'>";
39-
var GRNct = "<span style='color:green;'>";
40-
var NOct = "</span>";
43+
const CYANct = "<span style='color:cyan;'>";
44+
const REDct = "<span style='color:red;'>";
45+
const GRNct = "<span style='color:green;'>";
46+
const NOct = "</span>";
4147
4248
/**-------------------------------------**/
4349
/** Added by Martinski W. [2025-Jan-05] **/
4450
/**-------------------------------------**/
45-
let InvGRNct = '<span style="margin-left:4px; background-color:#229652; color:#f2f2f2;">&nbsp;'
46-
let InvREDct = '<span style="margin-left:4px; background-color:#C81927; color:#f2f2f2;">&nbsp;'
47-
let InvYLWct = '<span style="margin-left:4px; background-color:yellow; color:black;">&nbsp;'
48-
let InvCYNct = '<span style="margin-left:4px; background-color:cyan; color:black;">&nbsp;'
49-
let InvCLEAR = '&nbsp;</span>'
51+
const InvGRNct = '<span style="margin-left:4px; background-color:#229652; color:#f2f2f2;">&nbsp;'
52+
const InvREDct = '<span style="margin-left:4px; background-color:#C81927; color:#f2f2f2;">&nbsp;'
53+
const InvYLWct = '<span style="margin-left:4px; background-color:yellow; color:black;">&nbsp;'
54+
const InvCYNct = '<span style="margin-left:4px; background-color:cyan; color:black;">&nbsp;'
55+
const InvCLEAR = '&nbsp;</span>'
5056
51-
// Separate variables for server and AJAX settings
52-
var advanced_settings = {};
53-
var custom_settings = {};
54-
var server_custom_settings = {};
55-
var ajax_custom_settings = {};
57+
/**-------------------------------------**/
58+
/** Added by Martinski W. [2025-Jan-13] **/
59+
/**-------------------------------------**/
60+
// To support 'fwUpdatePostponement' element //
61+
const fwPostponedDays =
62+
{
63+
minVal: 0, maxVal: 199, maxLen: 3,
64+
ErrorMsg: function()
65+
{
66+
return (`The number of postponement days for F/W updates is INVALID.\nThe value must be between ${this.minVal} and ${this.maxVal} days.`);
67+
},
68+
LabelText: function()
69+
{
70+
return (`F/W Update Postponement (${this.minVal} to ${this.maxVal} days)`);
71+
},
72+
ValidateNumber: function(formField)
73+
{
74+
const inputVal = (formField.value * 1);
75+
const inputLen = formField.value.length;
76+
if (inputLen === 0 || inputLen > this.maxLen ||
77+
inputVal < this.minVal || inputVal > this.maxVal)
78+
{ return false; }
79+
else
80+
{ return true; }
81+
}
82+
};
83+
84+
/**-------------------------------------**/
85+
/** Added by Martinski W. [2025-Jan-13] **/
86+
/**-------------------------------------**/
87+
function ValidatePostponedDays (formField)
88+
{
89+
if (fwPostponedDays.ValidateNumber(formField))
90+
{
91+
$(formField).removeClass('Invalid');
92+
$(formField).off('mouseover');
93+
return true;
94+
}
95+
else
96+
{
97+
formField.focus();
98+
$(formField).addClass('Invalid');
99+
$(formField).on('mouseover',function(){return overlib(fwPostponedDays.ErrorMsg(),0,0);});
100+
$(formField)[0].onmouseout = nd;
101+
return false;
102+
}
103+
}
104+
105+
/**-------------------------------------**/
106+
/** Added by Martinski W. [2025-Jan-05] **/
107+
/**-------------------------------------**/
108+
function FormatNumericSetting(forminput)
109+
{
110+
let inputvalue = forminput.value * 1;
111+
112+
if (forminput.value.length === 0 || isNaN(inputvalue))
113+
{
114+
return false;
115+
}
116+
else
117+
{
118+
forminput.value = parseInt(forminput.value, 10);
119+
return true;
120+
}
121+
}
122+
123+
/**-------------------------------------**/
124+
/** Added by Martinski W. [2025-Jan-13] **/
125+
/**-------------------------------------**/
126+
// To support 'routerPassword' element //
127+
const loginPassword =
128+
{
129+
minLen: 5, maxLen: 64, currLen: 0,
130+
ErrorMsg: function()
131+
{
132+
const errStr = 'The password string is INVALID.';
133+
if (this.currLen < this.minLen)
134+
{
135+
const excMinLen = (this.minLen - 1);
136+
return (`${errStr}\nThe string length must be greater than ${excMinLen} characters.`);
137+
}
138+
if (this.currLen > this.maxLen)
139+
{
140+
const excMaxLen = (this.maxLen + 1);
141+
return (`${errStr}\nThe string length must be less than ${excMaxLen} characters.`);
142+
}
143+
},
144+
ValidateString: function(formField)
145+
{
146+
const inputVal = formField.value;
147+
const inputLen = formField.value.length;
148+
this.currLen = inputLen;
149+
if (inputLen < this.minLen || inputLen > this.maxLen)
150+
{ return false; }
151+
else
152+
{ return true; }
153+
}
154+
};
155+
156+
/**-------------------------------------**/
157+
/** Added by Martinski W. [2025-Jan-13] **/
158+
/**-------------------------------------**/
159+
function ValidatePasswordString (formField)
160+
{
161+
if (loginPassword.ValidateString(formField))
162+
{
163+
$(formField).removeClass('Invalid');
164+
$(formField).off('mouseover');
165+
return true;
166+
}
167+
else
168+
{
169+
formField.focus();
170+
$(formField).addClass('Invalid');
171+
$(formField).on('mouseover',function(){return overlib(loginPassword.ErrorMsg(),0,0);});
172+
$(formField)[0].onmouseout = nd;
173+
return false;
174+
}
175+
}
56176
57177
function togglePassword()
58178
{
59179
const passInput = document.getElementById('routerPassword');
60180
const eyeDiv = document.getElementById('eyeToggle');
61181
62-
// Base64-encoded SVG strings
182+
// Base64-encoded SVG strings //
63183
const eyeOpenSVG = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxwYXRoIGQ9Ik0xLjI2IDkuNkE2Ljk3IDYuOTcgMCAwMTggNGMzLjIgMCA2LjA2IDIuMzMgNi43NCA1LjZhLjUuNSAwIDAwLjk4LS4yQTcuOTcgNy45NyAwIDAwOCAzIDcuOTcgNy45NyAwIDAwLjI4IDkuNGEuNS41IDAgMDAuOTguMnoiIGZpbGw9IldpbmRvd1RleHQiLz48cGF0aCBkPSJNOCA2YTMuNSAzLjUgMCAxMDAgNyAzLjUgMy41IDAgMDAwLTd6TTUuNSA5LjVhMi41IDIuNSAwIDExNSAwIDIuNSAyLjUgMCAwMS01IDB6IiBmaWxsPSJXaW5kb3dUZXh0Ii8+DQo8L3N2Zz4=";
184+
64185
const eyeClosedSVG = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIGZpbGw9IldpbmRvd1RleHQiPjxwYXRoIGQ9Ik0uODUuMTVhLjUuNSAwIDEwLS43LjdsMy41IDMuNUE4LjEgOC4xIDAgMDAuMjggOS40YS41LjUgMCAwMC45OC4yIDcuMDkgNy4wOSAwIDAxMy4xLTQuNTNsMS42IDEuNTlhMy41IDMuNSAwIDEwNC44OCA0Ljg5bDQuMyA0LjNhLjUuNSAwIDAwLjcxLS43bC0xNS0xNXptOS4yNyAxMC42OGEyLjUgMi41IDAgMTEtMy40NS0zLjQ1bDMuNDUgMy40NXoiLz48cGF0aCBkPSJNOC4xMiA2bDMuMzggMy4zOEEzLjUgMy41IDAgMDA4LjEyIDZ6Ii8+PHBhdGggZD0iTTggNGMtLjU3IDAtMS4xMy4wNy0xLjY3LjIxbC0uOC0uOEE3LjY1IDcuNjUgMCAwMTggM2MzLjcgMCA2Ljk0IDIuNjcgNy43MiA2LjRhLjUuNSAwIDAxLS45OC4yQTYuOTcgNi45NyAwIDAwOCA0eiIvPjwvZz48ZGVmcz48Y2xpcFBhdGggaWQ9ImNsaXAwIj48cGF0aCBmaWxsPSIjZmZmZmZmIiBkPSJNMCAwaDE2djE2SDB6Ii8+PC9jbGlwUGF0aD48L2RlZnM+DQo8L3N2Zz4=";
65186
66187
if (passInput.type === 'password')
@@ -118,47 +239,6 @@ function FWVersionStrToNum(verStr)
118239
return (verNum);
119240
}
120241
121-
/**-------------------------------------**/
122-
/** Added by Martinski W. [2025-Jan-05] **/
123-
/**-------------------------------------**/
124-
function ValidateNumericValue(forminput, lowerlimit, upperlimit)
125-
{
126-
let inputname = forminput.name;
127-
let inputvalue = forminput.value * 1;
128-
129-
if (forminput.value.length === 0 ||
130-
inputvalue < lowerlimit ||
131-
inputvalue > upperlimit)
132-
{
133-
$(forminput).addClass('Invalid');
134-
return false;
135-
}
136-
else
137-
{
138-
$(forminput).removeClass('Invalid');
139-
return true;
140-
}
141-
}
142-
143-
/**-------------------------------------**/
144-
/** Added by Martinski W. [2025-Jan-05] **/
145-
/**-------------------------------------**/
146-
function FormatNumericSetting(forminput)
147-
{
148-
let inputname = forminput.name;
149-
let inputvalue = forminput.value * 1;
150-
151-
if (forminput.value.length === 0 || isNaN(inputvalue))
152-
{
153-
return false;
154-
}
155-
else
156-
{
157-
forminput.value = parseInt(forminput.value, 10);
158-
return true;
159-
}
160-
}
161-
162242
function LoadCustomSettings()
163243
{
164244
server_custom_settings = <% get_custom_settings(); %>;
@@ -214,7 +294,7 @@ function handleROGFWBuildTypeVisibility()
214294
}
215295
216296
/**----------------------------------------**/
217-
/** Modified by Martinski W. [2025-Jan-11] **/
297+
/** Modified by Martinski W. [2025-Jan-13] **/
218298
/**----------------------------------------**/
219299
function initializeFields()
220300
{
@@ -259,7 +339,11 @@ function initializeFields()
259339
{ routerPassword.value = custom_settings.routerPassword || ''; }
260340
261341
if (fwUpdatePostponement)
262-
{ fwUpdatePostponement.value = custom_settings.FW_New_Update_Postponement_Days || '15'; }
342+
{
343+
fwPosptonedDaysLabel = document.getElementById('fwUpdatePostponementLabel');
344+
fwPosptonedDaysLabel.textContent = fwPostponedDays.LabelText();
345+
fwUpdatePostponement.value = custom_settings.FW_New_Update_Postponement_Days || '15';
346+
}
263347
264348
if (secondaryEmail)
265349
{ secondaryEmail.value = custom_settings.FW_New_Update_EMail_CC_Address || ''; }
@@ -698,15 +782,15 @@ function initial()
698782
}
699783
700784
/**----------------------------------------**/
701-
/** Modified by Martinski W. [2025-Jan-05] **/
785+
/** Modified by Martinski W. [2025-Jan-13] **/
702786
/**----------------------------------------**/
703787
function SaveActionsConfig()
704788
{
705789
// Clear amng_custom for any existing content before saving
706790
document.getElementById('amng_custom').value = '';
707791
708792
// Collect Action form-specific settings //
709-
var password = document.getElementById('routerPassword')?.value || '';
793+
var passwordStr = document.getElementById('routerPassword')?.value || '';
710794
var usernameElement = document.getElementById('http_username');
711795
var username = usernameElement ? usernameElement.value.trim() : 'admin';
712796
@@ -717,18 +801,24 @@ function SaveActionsConfig()
717801
alert("HTTP username is not set. Please contact your administrator.");
718802
return false;
719803
}
720-
if (!ValidateNumericValue(document.form.fwUpdatePostponement,0,199))
804+
if (!ValidatePasswordString (document.getElementById('routerPassword')))
805+
{
806+
alert('Validation failed. Please correct invalid value and try again.\n\n' + loginPassword.ErrorMsg());
807+
return false;
808+
}
809+
if (!ValidatePostponedDays (document.form.fwUpdatePostponement))
721810
{
722-
alert("The number of postponement days for F/W updates is INVALID.");
811+
alert('Validation failed. Please correct invalid value and try again.\n\n' + fwPostponedDays.ErrorMsg());
723812
return false;
724813
}
725814
726815
// Encode credentials in Base64 //
727-
var credentials = username + ':' + password;
816+
var credentials = username + ':' + passwordStr;
728817
var encodedCredentials = btoa(credentials);
729818
730819
// Collect only Action form-specific settings
731-
var action_settings = {
820+
var action_settings =
821+
{
732822
credentials_base64: encodedCredentials,
733823
FW_New_Update_Postponement_Days: document.getElementById('fwUpdatePostponement')?.value || '0',
734824
CheckChangeLog: document.getElementById('changelogCheckEnabled').checked ? 'ENABLED' : 'DISABLED',
@@ -1218,23 +1308,23 @@ function initializeCollapsibleSections()
12181308
placeholder="Enter password"
12191309
style="width: 100%; display: inline-block;
12201310
padding-right: 35px;
1221-
box-sizing: border-box;
1222-
"
1311+
box-sizing: border-box;"
1312+
maxlength="64"
1313+
onKeyPress="return validator.isString(this, event)"
1314+
onblur="ValidatePasswordString(this)"
1315+
onkeyup="ValidatePasswordString(this)"
12231316
/>
12241317
<div
12251318
id="eyeToggle"
12261319
onclick="togglePassword();"
12271320
style="
12281321
position: absolute;
1229-
right: 5px;
1230-
top: 50%;
1322+
right: 5px; top: 50%;
12311323
transform: translateY(-50%);
1232-
width: 20px;
1233-
height: 20px;
1324+
width: 20px; height: 20px;
12341325
background: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxwYXRoIGQ9Ik0xLjI2IDkuNkE2Ljk3IDYuOTcgMCAwMTggNGMzLjIgMCA2LjA2IDIuMzMgNi43NCA1LjZhLjUuNSAwIDAwLjk4LS4yQTcuOTcgNy45NyAwIDAwOCAzIDcuOTcgNy45NyAwIDAwLjI4IDkuNGEuNS41IDAgMDAuOTguMnoiIGZpbGw9IldpbmRvd1RleHQiLz48cGF0aCBkPSJNOCA2YTMuNSAzLjUgMCAxMDAgNyAzLjUgMy41IDAgMDAwLTd6TTUuNSA5LjVhMi41IDIuNSAwIDExNSAwIDIuNSAyLjUgMCAwMS01IDB6IiBmaWxsPSJXaW5kb3dUZXh0Ii8+DQo8L3N2Zz4=') no-repeat center;
12351326
background-size: contain;
1236-
cursor: pointer;
1237-
"
1327+
cursor: pointer;"
12381328
></div>
12391329
</div>
12401330
</td>
@@ -1245,11 +1335,14 @@ function initializeCollapsibleSections()
12451335
</tr>
12461336
<tr>
12471337
<td style="text-align: left;">
1248-
<label for="fwUpdatePostponement">F/W Update Postponement (0-199 days)</label>
1338+
<label id="fwUpdatePostponementLabel" for="fwUpdatePostponement">F/W Update Postponement</label>
12491339
</td>
12501340
<td class="settingvalue">
1251-
<input autocomplete="off" type="text" id="fwUpdatePostponement" name="fwUpdatePostponement" style="width: 26%;" min="0" max="199" maxlength="3" onkeypress="return validator.isNumber(this,event)" onblur="ValidateNumericValue(this,0,199);FormatNumericSetting(this)"
1252-
onkeyup="ValidateNumericValue(this,0,199)" />
1341+
<input autocomplete="off" type="text" id="fwUpdatePostponement" name="fwUpdatePostponement" style="width: 15%;"
1342+
maxlength="3"
1343+
onKeyPress="return validator.isNumber(this,event)"
1344+
onblur="ValidatePostponedDays(this);FormatNumericSetting(this)"
1345+
onkeyup="ValidatePostponedDays(this)" />
12531346
</td>
12541347
</tr>
12551348
<tr>

MerlinAU.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55
# Original Creation Date: 2023-Oct-01 by @ExtremeFiretop.
66
# Official Co-Author: @Martinski W. - Date: 2023-Nov-01
7-
# Last Modified: 2025-Jan-12
7+
# Last Modified: 2025-Jan-13
88
###################################################################
99
set -u
1010

@@ -3379,7 +3379,7 @@ _GetKeypressInput_()
33793379
##----------------------------------------##
33803380
_GetPasswordInput_()
33813381
{
3382-
local PSWDstrLenMIN=1 PSWDstrLenMAX=64
3382+
local PSWDstrLenMIN=5 PSWDstrLenMAX=64
33833383
local newPSWDstring newPSWDtmpStr PSWDprompt
33843384
local retCode charNum newPSWDlength showPSWD
33853385
# For more responsive TAB keypress debounce #

0 commit comments

Comments
 (0)