44 < meta charset ="UTF-8 " />
55 < meta name ="viewport " content ="width=device-width, initial-scale=1.0 " />
66 < title > Password Change Required - MCP Gateway</ title >
7+ <!-- Tailwind CSS -->
8+ {% if ui_airgapped %}
9+ < script src ="{{ root_path }}/static/vendor/tailwindcss/tailwind.min.js "> </ script >
10+ {% else %}
711 < script src ="https://cdn.tailwindcss.com "> </ script >
12+ {% endif %}
813 < script >
914 tailwind . config = {
1015 darkMode : "class" ,
5459 } ,
5560 } ;
5661 </ script >
57- < link
58- rel ="stylesheet "
59- href ="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css "
60- />
62+ <!-- Font Awesome -->
63+ {% if ui_airgapped %}
64+ < link rel ="stylesheet " href ="{{ root_path }}/static/vendor/fontawesome/css/all.min.css " />
65+ {% else %}
66+ < link rel ="stylesheet " href ="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css " />
67+ {% endif %}
6168 </ head >
6269 < body class ="h-full bg-gray-50 dark:bg-gray-900 overflow-hidden ">
6370 <!-- Main Split Layout -->
@@ -223,21 +230,33 @@ <h3 class="text-sm font-semibold text-blue-700 dark:text-blue-300 mb-2">
223230 </ h3 >
224231 < ul class ="text-xs text-blue-600 dark:text-blue-400 space-y-1 ">
225232 < li id ="req-length " class ="flex items-center ">
226- < i class ="fas fa-circle text-green-500 mr-2 "> </ i >
227- At least 8 characters long
233+ < i class ="fas fa-circle text-gray-400 mr-2 "> </ i >
234+ At least {{ password_min_length or 8 }} characters long
228235 </ li >
236+ {% if password_require_uppercase %}
229237 < li id ="req-uppercase " class ="flex items-center ">
230- < i class ="fas fa-circle text-green-500 mr-2 "> </ i >
238+ < i class ="fas fa-circle text-gray-400 mr-2 "> </ i >
231239 Contains uppercase letters (A-Z)
232240 </ li >
241+ {% endif %}
242+ {% if password_require_lowercase %}
233243 < li id ="req-lowercase " class ="flex items-center ">
234- < i class ="fas fa-circle text-green-500 mr-2 "> </ i >
244+ < i class ="fas fa-circle text-gray-400 mr-2 "> </ i >
235245 Contains lowercase letters (a-z)
236246 </ li >
247+ {% endif %}
248+ {% if password_require_numbers %}
249+ < li id ="req-numbers " class ="flex items-center ">
250+ < i class ="fas fa-circle text-gray-400 mr-2 "> </ i >
251+ Contains numbers (0-9)
252+ </ li >
253+ {% endif %}
254+ {% if password_require_special %}
237255 < li id ="req-special " class ="flex items-center ">
238- < i class ="fas fa-circle text-green-500 mr-2 "> </ i >
239- Contains special characters (!@#$%&* )
256+ < i class ="fas fa-circle text-gray-400 mr-2 "> </ i >
257+ Contains special characters (!@#$%^&*()_+[]{}:;"'<>?,. )
240258 </ li >
259+ {% endif %}
241260 </ ul >
242261 </ div >
243262
@@ -461,6 +480,15 @@ <h4 class="text-sm font-semibold text-white mb-2">
461480 }
462481 }
463482
483+ // Password policy settings from server
484+ const passwordPolicy = {
485+ minLength : { { password_min_length | tojson } } || 8 ,
486+ requireUppercase : { { password_require_uppercase | tojson } } ,
487+ requireLowercase : { { password_require_lowercase | tojson } } ,
488+ requireNumbers : { { password_require_numbers | tojson } } ,
489+ requireSpecial : { { password_require_special | tojson } }
490+ } ;
491+
464492 // Validate password requirements
465493 function validatePassword ( ) {
466494 const password = document . getElementById ( 'new_password' ) . value ;
@@ -471,18 +499,22 @@ <h4 class="text-sm font-semibold text-white mb-2">
471499 strengthElement . textContent = strength . label ;
472500 strengthElement . className = `font-medium ${ strength . color } ` ;
473501
474- // Update requirement indicators
475- updateRequirement ( 'req-length' , password . length >= 8 ) ;
476- updateRequirement ( 'req-uppercase' , / [ A - Z ] / . test ( password ) ) ;
477- updateRequirement ( 'req-lowercase' , / [ a - z ] / . test ( password ) ) ;
478- updateRequirement ( 'req-special' , / [ ! @ # $ % ^ & * ( ) _ + \- = \[ \] { } ; ' : " \\ | , . < > \/ ? ] / . test ( password ) ) ;
502+ // Update requirement indicators (only for elements that exist)
503+ updateRequirement ( 'req-length' , password . length >= passwordPolicy . minLength ) ;
504+ if ( passwordPolicy . requireUppercase ) updateRequirement ( 'req-uppercase' , / [ A - Z ] / . test ( password ) ) ;
505+ if ( passwordPolicy . requireLowercase ) updateRequirement ( 'req-lowercase' , / [ a - z ] / . test ( password ) ) ;
506+ if ( passwordPolicy . requireNumbers ) updateRequirement ( 'req-numbers' , / [ 0 - 9 ] / . test ( password ) ) ;
507+ if ( passwordPolicy . requireSpecial ) updateRequirement ( 'req-special' , / [ ! @ # $ % ^ & * ( ) _ + \- = \[ \] { } ; ' : " \\ | , . < > \/ ? ] / . test ( password ) ) ;
508+
509+ // Check password match after validation
510+ validatePasswordMatch ( ) ;
479511 }
480512
481513 // Get password strength
482514 function getPasswordStrength ( password ) {
483515 let score = 0 ;
484516
485- if ( password . length >= 8 ) score ++ ;
517+ if ( password . length >= passwordPolicy . minLength ) score ++ ;
486518 if ( / [ A - Z ] / . test ( password ) ) score ++ ;
487519 if ( / [ a - z ] / . test ( password ) ) score ++ ;
488520 if ( / [ 0 - 9 ] / . test ( password ) ) score ++ ;
@@ -493,10 +525,12 @@ <h4 class="text-sm font-semibold text-white mb-2">
493525 return { label : 'Strong' , color : 'text-green-500' } ;
494526 }
495527
496- // Update requirement indicator
528+ // Update requirement indicator (only if element exists)
497529 function updateRequirement ( id , met ) {
498530 const element = document . getElementById ( id ) ;
531+ if ( ! element ) return ;
499532 const icon = element . querySelector ( 'i' ) ;
533+ if ( ! icon ) return ;
500534
501535 if ( met ) {
502536 icon . className = 'fas fa-check-circle text-green-500 mr-2' ;
@@ -522,12 +556,14 @@ <h4 class="text-sm font-semibold text-white mb-2">
522556 }
523557 }
524558
525- // Check if password is valid
559+ // Check if password is valid based on policy
526560 function isPasswordValid ( password ) {
527- return password . length >= 8 &&
528- / [ A - Z ] / . test ( password ) &&
529- / [ a - z ] / . test ( password ) &&
530- / [ ! @ # $ % ^ & * ( ) _ + \- = \[ \] { } ; ' : " \\ | , . < > \/ ? ] / . test ( password ) ;
561+ const lengthOk = password . length >= passwordPolicy . minLength ;
562+ const uppercaseOk = ! passwordPolicy . requireUppercase || / [ A - Z ] / . test ( password ) ;
563+ const lowercaseOk = ! passwordPolicy . requireLowercase || / [ a - z ] / . test ( password ) ;
564+ const numbersOk = ! passwordPolicy . requireNumbers || / [ 0 - 9 ] / . test ( password ) ;
565+ const specialOk = ! passwordPolicy . requireSpecial || / [ ! @ # $ % ^ & * ( ) _ + \- = \[ \] { } ; ' : " \\ | , . < > \/ ? ] / . test ( password ) ;
566+ return lengthOk && uppercaseOk && lowercaseOk && numbersOk && specialOk ;
531567 }
532568
533569 // Handle error messages from URL parameters
0 commit comments