Website: update new password form (#43548)

Changes:
- Updated the new password form and change password form on the
logged-in customer dashboard to have the same password requirements the
register form
- Updated the button styles on the 498 response page

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Strengthened password requirements: 12–48 characters, must include at
least one number and one symbol.
  * More specific validation feedback for new/confirm password fields.

* **Bug Fixes**
* Modal focus behavior improved so password inputs receive focus when
opened.

* **Style**
  * Primary button styling applied to password actions.
  * Link hover visuals enhanced.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Eric
2026-04-14 13:51:00 -05:00
committed by GitHub
co-authored by Copilot
parent 10a7476ecc
commit 0d598f6c6b
7 changed files with 40 additions and 13 deletions
+8 -1
View File
@@ -62,7 +62,14 @@ parasails.registerPage('dashboard', {
this.formData = {};
this.formRules = {
oldPassword: {required: true},
newPassword: {required: true, minLength: 8},
newPassword: {
required: true,
minLength: 12,
maxLength: 48,
custom: (value)=>{
return value.match(/^(?=.*\d)(?=.*[^A-Za-z0-9]).{12,48}$/);
}
},
};
this.modal = 'update-password';
},
+14 -2
View File
@@ -15,8 +15,20 @@ parasails.registerPage('new-password', {
// Form rules
formRules: {
password: {required: true, minLength: 8},
confirmPassword: {required: true, minLength: 8, sameAs: 'password'},
password: {
required: true,
minLength: 12,
maxLength: 48,
custom: (value)=>{
return value.match(/^(?=.*\d)(?=.*[^A-Za-z0-9]).{12,48}$/);
}
},
confirmPassword: {
required: true,
minLength: 12,
maxLength: 48,
sameAs: 'password',
},
},
// Server error state for the form
+3 -1
View File
@@ -1,5 +1,7 @@
[id='498'] {
//…
a.btn:hover {
color: #FFF;
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
<hr/>
<div>
<p>Need further help accessing your account?<br class="d-none d-sm-inline" /><span class="d-inline d-sm-none">&nbsp;</span>Please <a href="/contact?sendMessage">contact support</a> or request a new <a href="/customers/forgot-password">password reset.</a></p>
<a class="btn btn-info" href="/customers/forgot-password">Reset password</a>
<a class="btn btn-primary" href="/customers/forgot-password">Reset password</a>
</div>
</div>
</div>
+1 -1
View File
@@ -929,8 +929,8 @@
<script src="/js/pages/landing-pages/basic-comparison.page.js"></script>
<script src="/js/pages/landing-pages/deployment.page.js"></script>
<script src="/js/pages/landing-pages/gitops-workshop.page.js"></script>
<script src="/js/pages/landing-pages/replace-jamf.page.js"></script>
<script src="/js/pages/landing-pages/linux-management.page.js"></script>
<script src="/js/pages/landing-pages/replace-jamf.page.js"></script>
<script src="/js/pages/legal/privacy.page.js"></script>
<script src="/js/pages/legal/terms.page.js"></script>
<script src="/js/pages/meetups.page.js"></script>
+6 -4
View File
@@ -181,21 +181,23 @@
<div class="modal-body">
<div class="form-group">
<label for="oldPassword">Current password</label>
<input class="form-control" type="password" id="oldPassword" :class="[formErrors.oldPassword ? 'is-invalid' : '']" v-model.trim="formData.oldPassword" autocomplete="password">
<input class="form-control" type="password" id="oldPassword" :class="[formErrors.oldPassword ? 'is-invalid' : '']" v-model.trim="formData.oldPassword" autocomplete="password" focus-first>
<div class="invalid-feedback" v-if="formErrors.oldPassword">Please enter your current password.</div>
</div>
<div class="form-group">
<label for="password">New password</label>
<input class="form-control" type="password" id="password" :class="[formErrors.newPassword ? 'is-invalid' : '']" v-model.trim="formData.newPassword">
<div class="invalid-feedback" v-if="formErrors.newPassword === 'minLength'">Password too short!</div>
<div class="invalid-feedback" v-else-if="formErrors.newPassword">Please enter your new password.</div>
<p class="mt-2"> Minimum length is 8 characters</p>
<div class="invalid-feedback" v-else-if="formErrors.newPassword === 'maxLength'">Password too long!</div>
<div class="invalid-feedback" v-else-if="formErrors.newPassword === 'custom'">New password does not meet requirements.</div>
<div class="invalid-feedback" v-else-if="formErrors.newPassword === 'required'">Please enter your new password.</div>
<p class="mt-2">Passwords must be 12-48 characters, with at least 1 number (e.g. 0 - 9) and 1 symbol (e.g. &*#).</p>
</div>
<cloud-error v-if="cloudError === 'badPassword'">Incorrect current password.</cloud-error>
<cloud-error v-else-if="cloudError"></cloud-error>
</div>
<div class="border-0 justify-content-center">
<ajax-button purpose="submit-button" spinner="true" type="submit" :syncing="syncing" class="btn btn-sm btn-block btn-info" focus-first>Save</ajax-button>
<ajax-button purpose="submit-button" spinner="true" type="submit" :syncing="syncing" class="btn btn-sm btn-primary" >Save</ajax-button>
</div>
</ajax-form>
</div>
+7 -3
View File
@@ -9,16 +9,20 @@
<input class="form-control" id="password" name="password" type="password" :class="[formErrors.password ? 'is-invalid' : '']" v-model.trim="formData.password" autocomplete="new-password" focus-first>
<div class="invalid-feedback" v-if="formErrors.password === 'required'">Please enter a password.</div>
<div class="invalid-feedback" v-if="formErrors.password === 'minLength'">Password too short.</div>
<p class="mt-2"> Minimum length is 8 characters</p>
<div class="invalid-feedback" v-if="formErrors.password === 'maxLength'">Password too long.</div>
<div class="invalid-feedback" v-if="formErrors.password === 'custom'">Password does not meet requirements.</div>
<p purpose="modal-form-note" class="mt-2">Passwords must be 12-48 characters, with at least 1 number (e.g. 0 - 9) and 1 symbol (e.g. &*#).</p>
</div>
<div class="form-group">
<label for="confirm-password">Confirm password</label>
<input class="form-control" id="confirm-password" name="confirm-password" type="password" :class="[formErrors.confirmPassword ? 'is-invalid' : '']" v-model.trim="formData.confirmPassword" autocomplete="new-password">
<div class="invalid-feedback" v-if="formErrors.password === 'minLength'">Password too short.</div>
<div class="invalid-feedback" v-if="formErrors.confirmPassword">Your new password and confirmation do not match.</div>
<div class="invalid-feedback" v-if="formErrors.password === 'custom'">Password does not meet requirements.</div>
<div class="invalid-feedback" v-if="formErrors.confirmPassword === 'sameAs'">Your new password and confirmation do not match.</div>
</div>
<cloud-error v-if="cloudError"></cloud-error>
<ajax-button purpose="submit-button" spinner="true" type="submit" :syncing="syncing" class="btn btn-info btn-lg btn-block">Submit</ajax-button>
<ajax-button purpose="submit-button" spinner="true" type="submit" :syncing="syncing" class="btn btn-primary">Submit</ajax-button>
</ajax-form>
</div>
</div>