✅ Implemented: - Password hashing with bcrypt (salt rounds = 10) - JWT token generation (access 15m, refresh 7d) - Updated login endpoint to return access + refresh tokens - Added refresh and logout endpoints - Updated seed script with hashed passwords - Added test users for all roles (OWNER, MANAGER, GROWER, STAFF) 📝 Files Added/Modified: - backend/src/utils/password.ts (NEW) - backend/src/utils/jwt.ts (NEW) - backend/src/controllers/auth.controller.ts (UPDATED) - backend/src/routes/auth.routes.ts (UPDATED) - backend/prisma/seed.js (UPDATED - now hashes passwords) - CREDENTIALS.md (UPDATED - all test users documented) 🔐 Test Users: - admin@runfoo.run (OWNER) - manager@runfoo.run (MANAGER) - grower@runfoo.run (GROWER) - staff@runfoo.run (STAFF) All passwords: password123 ⏭️ Next: Auth middleware + RBAC
94 lines
2.4 KiB
JavaScript
94 lines
2.4 KiB
JavaScript
const { PrismaClient } = require('@prisma/client');
|
|
const bcrypt = require('bcrypt');
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
const Role = {
|
|
OWNER: 'OWNER',
|
|
MANAGER: 'MANAGER',
|
|
GROWER: 'GROWER',
|
|
STAFF: 'STAFF'
|
|
};
|
|
|
|
const RoomType = {
|
|
VEG: 'VEG',
|
|
FLOWER: 'FLOWER',
|
|
DRY: 'DRY',
|
|
CURE: 'CURE',
|
|
MOTHER: 'MOTHER',
|
|
CLONE: 'CLONE'
|
|
};
|
|
|
|
async function main() {
|
|
console.log('Seeding database...');
|
|
|
|
// Hash password once for all users
|
|
const hashedPassword = await bcrypt.hash('password123', 10);
|
|
|
|
// Create test users for each role
|
|
const users = [
|
|
{
|
|
email: 'admin@runfoo.run',
|
|
passwordHash: hashedPassword,
|
|
name: 'Facility Owner',
|
|
role: Role.OWNER,
|
|
rate: 50.00
|
|
},
|
|
{
|
|
email: 'manager@runfoo.run',
|
|
passwordHash: hashedPassword,
|
|
name: 'Operations Manager',
|
|
role: Role.MANAGER,
|
|
rate: 35.00
|
|
},
|
|
{
|
|
email: 'grower@runfoo.run',
|
|
passwordHash: hashedPassword,
|
|
name: 'Head Grower',
|
|
role: Role.GROWER,
|
|
rate: 30.00
|
|
},
|
|
{
|
|
email: 'staff@runfoo.run',
|
|
passwordHash: hashedPassword,
|
|
name: 'Floor Staff',
|
|
role: Role.STAFF,
|
|
rate: 20.00
|
|
}
|
|
];
|
|
|
|
for (const userData of users) {
|
|
const existing = await prisma.user.findUnique({ where: { email: userData.email } });
|
|
if (!existing) {
|
|
await prisma.user.create({ data: userData });
|
|
console.log(`Created ${userData.role}: ${userData.email} / password123`);
|
|
}
|
|
}
|
|
|
|
// Create Default Rooms
|
|
const rooms = [
|
|
{ name: 'Veg Room 1', type: RoomType.VEG, sqft: 1200 },
|
|
{ name: 'Flower Room A', type: RoomType.FLOWER, sqft: 2500 },
|
|
{ name: 'Flower Room B', type: RoomType.FLOWER, sqft: 2500 },
|
|
{ name: 'Dry Room', type: RoomType.DRY, sqft: 800 },
|
|
];
|
|
|
|
for (const r of rooms) {
|
|
const existing = await prisma.room.findFirst({ where: { name: r.name } });
|
|
if (!existing) {
|
|
await prisma.room.create({ data: r });
|
|
console.log(`Created Room: ${r.name}`);
|
|
}
|
|
}
|
|
|
|
console.log('Seeding complete.');
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error(e);
|
|
process.exit(1);
|
|
})
|
|
.finally(async () => {
|
|
await prisma.$disconnect();
|
|
});
|