Skip to content

Commit f834d78

Browse files
committed
feat(auth): add admin-only user registration and improve JWT Handling
Implemented secure admin-only user creation flow and improved authentication middleware. - Protected POST /auth/register (valid JWT + ADMIN role) - Auth middleware to validate tokens and handle expiration. - Prisma User Creation (role enum + hashed passwords) Completed the backend portion of the authentication/authorization loop.
1 parent 2cba578 commit f834d78

File tree

12 files changed

+502
-5
lines changed

12 files changed

+502
-5
lines changed

package-lock.json

Lines changed: 198 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"build": "tsc",
99
"start": "node dist/server.js",
1010
"lint": "echo \"no linting yet\"",
11-
"test": "echo \"No test specified\""
11+
"test": "echo \"No test specified\"",
12+
"seed": "ts-node prisma/seed.ts"
1213
},
1314
"repository": {
1415
"type": "git",
@@ -28,15 +29,19 @@
2829
"@types/cors": "^2.8.19",
2930
"@types/express": "^5.0.6",
3031
"@types/node": "^25.2.0",
32+
"bcrypt": "^6.0.0",
3133
"cors": "^2.8.6",
3234
"dotenv": "^17.2.3",
3335
"express": "^5.2.1",
3436
"jest": "^30.2.0",
37+
"jsonwebtoken": "^9.0.3",
3538
"ts-node-dev": "^2.0.0"
3639
},
3740
"devDependencies": {
41+
"@types/bcrypt": "^6.0.0",
3842
"@types/jest": "^30.0.0",
43+
"@types/jsonwebtoken": "^9.0.10",
3944
"prisma": "^7.3.0",
4045
"typescript": "^5.9.3"
4146
}
42-
}
47+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- CreateEnum
2+
CREATE TYPE "Role" AS ENUM ('ADMIN', 'DOCTOR', 'RECEPTIONIST');

prisma/schema.prisma

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@ model User {
1111
id String @id @default(cuid())
1212
email String @unique
1313
password String
14-
role String // 'admin' | 'doctor' | 'receptionist'
14+
role String
1515
createdAt DateTime @default(now())
1616
updatedAt DateTime @updatedAt
1717
}
1818

19+
enum Role {
20+
ADMIN
21+
DOCTOR
22+
RECEPTIONIST
23+
}
24+
1925
model Patient {
2026
id String @id @default(cuid())
2127
firstName String

prisma/seed.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import dotenv from 'dotenv';
2+
import { PrismaPg } from '@prisma/adapter-pg';
3+
import { PrismaClient, Role } from '../src/config/generated/client';
4+
import bcrypt from 'bcrypt';
5+
6+
dotenv.config();
7+
8+
// Initialize Prisma Client with PSQL Adapter. ;(
9+
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
10+
const prisma = new PrismaClient({ adapter });
11+
const SALT_ROUNDS = 10;
12+
13+
// Seed main function to create an admin user.
14+
async function main() {
15+
const email = 'admin@medsoft.local';
16+
const password = 'adminDoc123!';
17+
18+
// Check if admin user already exists.
19+
const existing = await prisma.user.findUnique({ where: { email } });
20+
if (existing) {
21+
console.log('Admin user already exists. Skipping creation...');
22+
return;
23+
}
24+
25+
// Hash new password and create admin user.
26+
const hash = await bcrypt.hash(password, SALT_ROUNDS);
27+
28+
// Create admin user.
29+
await prisma.user.create({
30+
data: {
31+
email,
32+
password: hash,
33+
role: Role.ADMIN,
34+
},
35+
});
36+
37+
// Log admin user email + password.. (Remove in prod).
38+
console.log('Admin user created with email: ' + email + ' and a password: ' + password);
39+
}
40+
41+
// Execute the main function to seed the database with an admin user (testing only).
42+
main()
43+
.catch(console.error)
44+
.finally(async () => {
45+
await prisma.$disconnect();
46+
});

0 commit comments

Comments
 (0)