I have a single form that I want to authenticate users (doctors, patients, and admins). I am using Node for the backend and MySQL for the database.
Backend Server setup:
// import neccessary packages
const db = require('./config/db') // database conn
const express = require('express') // web server
const cors = require('cors')
const bodyParser = require('body-parser') // capture form data
const session = require('express-session'); // session-management
const MySQLStore = require('express-mysql-session')(session); // session-management storage
require('dotenv').config() // manage environment variables
const path = require('path')
const app = express()
// middleware
app.use(cors({
origin: ['http://127.0.0.1:5500', 'http://localhost:5500'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
credentials: true
}));
app.use(express.static(path.join(__dirname, '../client/index.html')))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true })) // capture form data
// sesssion store
const sessionStore = new MySQLStore({}, db)
// configure session middleware
app.use(session({
secret: process.env.SESSION_SECRET,
store: sessionStore,
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 1000 * 60 * 60 // 1 hour
}
}))
// routes
app.use('/telemedicine/api/patients', require('./routes/patientRoutes'))
app.use('/telemedicine/api/providers', require('./routes/providerRoutes.js'))
app.use('/telemedicine/api/admin', require('./routes/adminRoutes.js'))
// fetch for the html file
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, '../client/', 'index.html'))
})
// Patient Dashboard
app.get('/dashoard', (req, res) => {
res.sendFile(path.join(__dirname, '../client/patient', 'dashboard.html'))
})
// Provider Dashboard
app.get('/dashoard', (req, res) => {
res.sendFile(path.join(__dirname, '../client/doctor', 'dashboard.html'))
})
// Admin Dashboard
app.get('/dashoard', (req, res) => {
res.sendFile(path.join(__dirname, '../client/admin', 'dashboard.html'))
})
const PORT = process.env.PORT || 3200
// start server
app.listen(PORT, () => {
console.log(`Server is running at http://localhost:${PORT}`)
})
I tried to use one API for my form to authenticate the user
register.html:
<div class="container register">
<div class="form__image register__image">
<img src="images/register.png" alt="registerImage" />
</div>
<div class="form__container">
<h3>Register</h3>
<form id="registerForm" method="POST" action="/register">
<!-- Role Selection -->
<div>
<p>Select type of account</p>
<div id="role-selection" class="selection">
<span data-role="patient">Patient</span>
<span data-role="provider">Doctor</span>
<span data-role="admin">Admin</span>
</div>
</div>
<!-- Form -->
<div class="form__field">
<div>
<input
type="text"
id="first_name"
name="first_name"
placeholder="First Name"
required
/>
<input
type="text"
id="last_name"
name="last_name"
placeholder="Last Name"
required
/>
<input
type="email"
id="email"
name="email"
placeholder="Email Address"
required
/>
<input
type="password"
id="password"
name="password"
placeholder="Password"
required
/>
</div>
<!-- Dynamic Fields based on Role -->
<div
id="patient-fields"
class="role-specific-fields"
style="display: none"
>
<input
type="date"
id="date_of_birth"
name="date_of_birth"
placeholder="Date of Birth"
required
/>
<div>
<select id="language" name="language" required>
<option value="">Select Language</option>
<option value="English">English</option>
<option value="Spanish">Spanish</option>
<option value="French">French</option>
</select>
<select id="gender" name="gender" required>
<option value="">Select Gender</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
<option value="Other">Other</option>
</select>
</div>
</div>
<div
id="provider-fields"
class="role-specific-fields"
style="display: none"
>
<input
type="text"
id="specialty"
name="specialty"
placeholder="Specialty"
required
/>
<input
type="text"
id="phone_number"
name="phone_number"
placeholder="Phone Number"
required
/>
</div>
</div>
<p>Already have an account ? <a href="login.html">Login</a></p>
<button type="submit">Register</button>
</form>
</div>
<div id="message" style="display: none"></div>
</div>
register.js:
// Role Selecetion
document.querySelectorAll('#role-selection span').forEach((span) => {
span.addEventListener('click', function() {
const selectedRole = this.getAttribute('data-role');
document.querySelectorAll('#role-selection span').forEach(s => s.classList.remove('selected'));
this.classList.add('selected');
const patientFields = document.getElementById('patient-fields');
const providerFields = document.getElementById('provider-fields');
patientFields.style.display = 'none';
providerFields.style.display = 'none';
// Reset required fields
const allRequiredFields = document.querySelectorAll('input[required], select[required]');
allRequiredFields.forEach(field => field.removeAttribute('required'));
if (selectedRole === 'patient') {
patientFields.style.display = 'flex';
patientFields.querySelectorAll('input, select').forEach(field => field.setAttribute('required', true));
} else if (selectedRole === 'provider') {
providerFields.style.display = 'flex';
providerFields.querySelectorAll('input').forEach(field => field.setAttribute('required', true));
}
document.getElementById('role-selection').setAttribute('data-selected-role', selectedRole);
});
});
// Handle Register
document.getElementById('registerForm').addEventListener('submit', async (e) => {
e.preventDefault();
const role = document.getElementById('role-selection').getAttribute('data-selected-role');
const first_name = document.getElementById('first_name').value;
const last_name = document.getElementById('last_name').value;
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
let date_of_birth = document.getElementById('date_of_birth') ? document.getElementById('date_of_birth').value : '';
let language = document.getElementById('language') ? document.getElementById('language').value : '';
let gender = document.getElementById('gender') ? document.getElementById('gender').value : '';
let specialty = document.getElementById('specialty') ? document.getElementById('specialty').value : '';
if (!role) {
return alert('Please select a role.');
}
if (!first_name || !last_name || !email || !password) {
return alert('Please fill in all required fields.');
}
if (role === 'patient' && (!date_of_birth || !language || !gender)) {
return alert('Please fill in all patient-specific fields.');
}
if (role === 'provider' && !specialty) {
return alert('Please provide your specialty.');
}
const response = await fetch('http://localhost:3200/telemedicine/api/patients/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ first_name, last_name, email, password, role, date_of_birth, language, gender, specialty }),
});
const data = await response.json();
if (response.ok) {
alert('Registration successful!');
window.location.href = '/login';
} else {
alert(data.message);
}
});
The user should be authenticated based on their role, then they should be redirected to their respective routes. However When I try to login or register, this is what I am getting
Failed to load resource: the server responded with a status of 400 (Bad Request)
register.js:67
POST http://localhost:3200/telemedicine/api/patients/register net::ERR_INTERNET_DISCONNECTED