Added password option in client registration
This commit is contained in:
parent
efa6ce929e
commit
5f043ed80a
|
|
@ -492,9 +492,11 @@ async function validateStep(step) {
|
||||||
} else if (step === 1) {
|
} else if (step === 1) {
|
||||||
const email = document.getElementById('email').value;
|
const email = document.getElementById('email').value;
|
||||||
const companyName = document.getElementById('company-name').value;
|
const companyName = document.getElementById('company-name').value;
|
||||||
if (!validateEmail(email) && !companyName) {
|
const password = document.getElementById('password').value;
|
||||||
|
const confirmPassword = document.getElementById('confirmPassword').value;
|
||||||
|
if (!validateEmail(email) && !companyName && !password && !confirmPassword) {
|
||||||
isValid = false;
|
isValid = false;
|
||||||
showError('Both Fields are Required', null, step);
|
showError('Fields are Required', null, step);
|
||||||
let requiredFields1 = form.querySelectorAll('[required]');
|
let requiredFields1 = form.querySelectorAll('[required]');
|
||||||
requiredFields1.forEach(field => {
|
requiredFields1.forEach(field => {
|
||||||
if (!field.value.trim()) {
|
if (!field.value.trim()) {
|
||||||
|
|
@ -522,6 +524,21 @@ async function validateStep(step) {
|
||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (password.length < 8) {
|
||||||
|
showError('Password must be at least 8 characters long', 'password', step);
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password !== confirmPassword) {
|
||||||
|
document.getElementById('password-match-error').style.display = 'block';
|
||||||
|
document.getElementById('confirmPassword').classList.add('field-error');
|
||||||
|
showError('Passwords do not match', 'confirmPassword', step);
|
||||||
|
isValid = false;
|
||||||
|
} else {
|
||||||
|
document.getElementById('password-match-error').style.display = 'none';
|
||||||
|
document.getElementById('confirmPassword').classList.remove('field-error');
|
||||||
|
}
|
||||||
|
|
||||||
// Validate other required fields
|
// Validate other required fields
|
||||||
const requiredFields = form.querySelectorAll('[required]');
|
const requiredFields = form.querySelectorAll('[required]');
|
||||||
requiredFields.forEach(field => {
|
requiredFields.forEach(field => {
|
||||||
|
|
@ -612,6 +629,7 @@ function saveStepData(step) {
|
||||||
case 1:
|
case 1:
|
||||||
formData.userDetails.name = document.getElementById('company-name').value;
|
formData.userDetails.name = document.getElementById('company-name').value;
|
||||||
formData.userDetails.email = document.getElementById('email').value;
|
formData.userDetails.email = document.getElementById('email').value;
|
||||||
|
formData.userDetails.password = document.getElementById('password').value;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
formData.userDetails.address = document.getElementById('address').value;
|
formData.userDetails.address = document.getElementById('address').value;
|
||||||
|
|
@ -1955,3 +1973,51 @@ function preventInvalidAccountHolderChars(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Function to generate a strong password
|
||||||
|
function generatePassword() {
|
||||||
|
const length = 12;
|
||||||
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*";
|
||||||
|
let password = "";
|
||||||
|
|
||||||
|
// Ensure at least one of each required character type
|
||||||
|
password += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(Math.random() * 26)];
|
||||||
|
password += "abcdefghijklmnopqrstuvwxyz"[Math.floor(Math.random() * 26)];
|
||||||
|
password += "0123456789"[Math.floor(Math.random() * 10)];
|
||||||
|
password += "!@#$%^&*"[Math.floor(Math.random() * 8)];
|
||||||
|
|
||||||
|
// Fill the rest randomly
|
||||||
|
for (let i = password.length; i < length; i++) {
|
||||||
|
password += charset.charAt(Math.floor(Math.random() * charset.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shuffle the password
|
||||||
|
password = password.split('').sort(() => 0.5 - Math.random()).join('');
|
||||||
|
|
||||||
|
// Set the password field
|
||||||
|
document.getElementById('password').value = password;
|
||||||
|
document.getElementById('confirmPassword').value = password;
|
||||||
|
|
||||||
|
// Trigger input events to update UI
|
||||||
|
document.getElementById('password').dispatchEvent(new Event('input'));
|
||||||
|
document.getElementById('confirmPassword').dispatchEvent(new Event('input'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to toggle password visibility
|
||||||
|
function togglePasswordVisibility() {
|
||||||
|
const passwordField = document.getElementById('password');
|
||||||
|
const confirmField = document.getElementById('confirmPassword');
|
||||||
|
const toggleButton = document.querySelector('.password-toggle');
|
||||||
|
|
||||||
|
if (passwordField.type === 'password') {
|
||||||
|
passwordField.type = 'text';
|
||||||
|
confirmField.type = 'text';
|
||||||
|
toggleButton.textContent = 'Hide Password';
|
||||||
|
} else {
|
||||||
|
passwordField.type = 'password';
|
||||||
|
confirmField.type = 'password';
|
||||||
|
toggleButton.textContent = 'Show Password';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -25,10 +25,10 @@ async function va_register_client(req, res) {
|
||||||
try {
|
try {
|
||||||
const payload = req.body || {};
|
const payload = req.body || {};
|
||||||
const { userDetails } = payload;
|
const { userDetails } = payload;
|
||||||
if (!userDetails || !userDetails.email || !userDetails.name) {
|
if (!userDetails || !userDetails.email || !userDetails.name || !userDetails.password) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: "Missing required fields: name and email are required"
|
message: "Missing required fields: name, email, and password are required"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ class VaClientService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanitize and prepare data
|
// Sanitize and prepare data
|
||||||
const clientData = this.sanitizeClientData(data);
|
const clientData = await this.sanitizeClientData(data);
|
||||||
const response = await this.clientRepository.create(clientData);
|
const response = await this.clientRepository.create(clientData);
|
||||||
|
|
||||||
if(response) {
|
if(response) {
|
||||||
|
|
@ -263,13 +263,17 @@ class VaClientService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method to sanitize data
|
// Helper method to sanitize data
|
||||||
sanitizeClientData(payload) {
|
async sanitizeClientData(payload) {
|
||||||
const { userDetails } = payload;
|
const { userDetails } = payload;
|
||||||
|
|
||||||
|
const saltRounds = 10;
|
||||||
|
const hashedPassword = await bcrypt.hash(userDetails.password, saltRounds);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
userDetails: {
|
userDetails: {
|
||||||
name: userDetails.name,
|
name: userDetails.name,
|
||||||
email: userDetails.email.toLowerCase(),
|
email: userDetails.email.toLowerCase(),
|
||||||
|
password: hashedPassword,
|
||||||
address: userDetails.address || null,
|
address: userDetails.address || null,
|
||||||
city: userDetails.city || null,
|
city: userDetails.city || null,
|
||||||
state: userDetails.state || null,
|
state: userDetails.state || null,
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,24 @@
|
||||||
<label for="email" class="input-label">Email *</label>
|
<label for="email" class="input-label">Email *</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="input-container">
|
||||||
|
<input type="password" id="password" class="input-field" placeholder=" " required autocomplete="new-password">
|
||||||
|
<label for="password" class="input-label">Create Password *</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="input-container">
|
||||||
|
<input type="password" id="confirmPassword" class="input-field" placeholder=" " required autocomplete="new-password">
|
||||||
|
<label for="confirmPassword" class="input-label">Confirm Password *</label>
|
||||||
|
</div>
|
||||||
|
<div class="invalid-feedback" id="password-match-error" style="display: none; color: #dc3545; font-size: 12px; margin-top: 5px;">Passwords do not match</div>
|
||||||
|
<div class="password-actions">
|
||||||
|
<button type="button" class="password-toggle" onclick="togglePasswordVisibility()">Show Password</button>
|
||||||
|
<button type="button" class="password-generate" onclick="generatePassword()">Generate Strong Password</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<div></div> <!-- Empty div for spacing -->
|
<div></div> <!-- Empty div for spacing -->
|
||||||
<button type="button" class="btn btn-primary" onclick="handleNextStep(2)">Continue</button>
|
<button type="button" class="btn btn-primary" onclick="handleNextStep(2)">Continue</button>
|
||||||
|
|
@ -242,7 +260,7 @@
|
||||||
<div class="error-message" id="step-4-error-message"></div>
|
<div class="error-message" id="step-4-error-message"></div>
|
||||||
</div>
|
</div>
|
||||||
<p style="margin-bottom: 20px; color: #6b7280; font-size: 14px;">
|
<p style="margin-bottom: 20px; color: #6b7280; font-size: 14px;">
|
||||||
We will use the details below in the agreement that we will send to your prior to entering the project.
|
We will use the details below in the agreement that we will send to your prior to starting the project.
|
||||||
</p>
|
</p>
|
||||||
<form id="signatory-form">
|
<form id="signatory-form">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
@ -322,7 +340,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="payment-option" onclick="selectPaymentOption('bank')">
|
<div class="payment-option" onclick="selectPaymentOption('bank')">
|
||||||
<h4>Bank Account (ACR)</h4>
|
<h4>Bank Account (ACH)</h4>
|
||||||
<p>Direct bank transfer</p>
|
<p>Direct bank transfer</p>
|
||||||
</div>
|
</div>
|
||||||
<div id="bank-details" class="payment-details">
|
<div id="bank-details" class="payment-details">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue