Skip to content

Commit 96538ec

Browse files
Merge pull request #11 from hms-int/main
Many changes
2 parents 492a22f + aac32df commit 96538ec

File tree

9 files changed

+112
-8
lines changed

9 files changed

+112
-8
lines changed

src/config/db.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import mongoose from 'mongoose';
33
const connectDB = async () => {
44
try {
55
await mongoose.connect(process.env.MONGO_URI);
6-
console.log('MongoDB connected');
76
} catch (error) {
87
console.error('DB connection failed', error);
98
process.exit(1);

src/controllers/authcontroller.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const login = async (req, res) => {
1717
const user = await User.findOne({
1818
email: { $regex: new RegExp(`^${email}$`, 'i') },
1919
role: { $regex: new RegExp(`^${role}$`, 'i') },
20-
}).select('email role status password');
20+
}).select('email role status password, mustchangepassword');
2121
if (!user) {
2222
return res.status(401).json({ success: false, message: 'Invalid role or email' });
2323
}
@@ -35,6 +35,15 @@ export const login = async (req, res) => {
3535
return res.status(403).json({ success: false, message: "Your account is currently inactive. Kindly reach out to the admin for support." });
3636
}
3737

38+
if (user.mustchangepassword) {
39+
return res.status(200).json({
40+
success: true,
41+
reuirePasswordChange: true,
42+
message: "You are required to change your password before proceeding.",
43+
email: user.email,
44+
});
45+
}
46+
3847
const token = jwt.sign(
3948
{ id: user._id, role: user.role, email: user.email },
4049
process.env.JWT_SECRET,

src/controllers/patient.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
import Patient from '../models/patient.js';
2+
import { createPatientPortalAccount } from '../services/patientPortal.service.js';
23

34
const createPatient = async (req, res, next) => {
45
try {
56
const patient = new Patient(req.body);
67
await patient.save();
7-
res.status(201).json(patient);
8+
9+
const { email, paymentMethod } = req.body;
10+
11+
if (paymentMethod === "online" && email) {
12+
await createPatientPortalAccount(email);
13+
}
14+
15+
res.status(201).json({
16+
success: true,
17+
patient
18+
});
19+
820
} catch (err) {
921
next(err);
1022
}

src/models/User.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,25 @@ const userSchema = new mongoose.Schema({
7272
match: /.+@.+\..+/
7373
},
7474

75+
patientId: {
76+
type: mongoose.Schema.Types.ObjectId,
77+
ref: "Patient"
78+
},
79+
7580
password: {
7681
type: String,
7782
required: true
7883
},
7984

85+
mustChangePassword: {
86+
type: Boolean,
87+
default: false
88+
},
89+
8090
role: {
8191
type: String,
8292
required: true,
83-
enum: ['admin', 'doctor','receptionist','billing']
93+
enum: ['admin', 'doctor','receptionist','billing','patient']
8494
},
8595

8696
name: { type: String },

src/models/patient.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ status:{
3232
default:'active',
3333
required:true
3434
},
35+
paymentMethod: {
36+
type: String,
37+
enum: ['cash', 'online'],
38+
default: 'cash'
39+
},
3540
bg:{
3641
type: String,
3742
enum:['A+','A-','B+','B-','AB+','AB-','O+','O-']

src/routes/patient.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import * as patientController from '../controllers/patient.js';
55
const router = express.Router();
66

77

8-
router.get('/', protect, authorize('admin', 'doctor'), patientController.getPatients);
8+
router.get('/', protect, authorize('admin', 'doctor','receptionist'), patientController.getPatients);
99

10-
router.post('/', protect, authorize('admin', 'doctor'), patientController.createPatient);
10+
router.post('/', protect, authorize('admin', 'doctor','receptionist'), patientController.createPatient);
1111

12-
router.put('/:id', protect, authorize('admin', 'doctor'), patientController.updatePatient);
12+
router.put('/:id', protect, authorize('admin', 'doctor','receptionist'), patientController.updatePatient);
1313

14-
router.delete('/:id', protect, authorize('admin'), patientController.deletePatient);
14+
router.delete('/:id', protect, authorize('admin','receptionist'), patientController.deletePatient);
1515

1616
export default router;

src/services/email.service.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,33 @@ export const sendOTPEmail = async (email, otp) => {
6060
</div>
6161
`
6262
});
63+
};
64+
65+
export const sendCredentialsEmail = async (email, password) => {
66+
await transporter.sendMail({
67+
from: `"HMS Team" <${process.env.GMAIL_EMAIL}>`,
68+
to: email,
69+
subject: "Your HMS Patient Portal Login Credentials",
70+
71+
html: `
72+
<div style="font-family: Arial; padding:20px;">
73+
<h2>Welcome to HMS Portal</h2>
74+
75+
<p>Your account has been created successfully.</p>
76+
77+
<p><b>Email:</b> ${email}</p>
78+
<p><b>Password:</b> ${password}</p>
79+
80+
<p>Please login and change your password immediately.</p>
81+
82+
<p>Login Link: <a href="https://hms-app/login">Login</a></p>
83+
84+
<hr/>
85+
86+
<p style="font-size:12px;color:#888;">
87+
This email was generated automatically.
88+
</p>
89+
</div>
90+
`
91+
});
6392
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import bcrypt from 'bcrypt';
2+
import User from '../models/User.js';
3+
import { generateRandomPassword } from '../utils/password.utils.js';
4+
import { sendCredentialsEmail } from './email.service.js';
5+
6+
export const createPatientPortalAccount = async (email) => {
7+
8+
try {const existingUser = await User.findOne({ email });
9+
10+
if (existingUser) {
11+
return;
12+
}
13+
14+
const rawPassword = generateRandomPassword(10);
15+
16+
const hashedPassword = await bcrypt.hash(rawPassword, 10);
17+
18+
const user = new User({
19+
email,
20+
password: hashedPassword,
21+
role: "patient",
22+
status: "Active",
23+
mustChangePassword: true
24+
});
25+
26+
await user.save();
27+
28+
await sendCredentialsEmail(email, rawPassword);
29+
} catch (err) {
30+
console.error("Patient pirtal account creation failed:", err);
31+
}
32+
};

src/utils/password.utils.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import crypto from 'crypto';
2+
3+
export const generateRandomPassword = (length = 10) => {
4+
return crypto
5+
.randomBytes(length)
6+
.toString('base64')
7+
.slice(0, length);
8+
};

0 commit comments

Comments
 (0)