@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "ClientUser" ADD COLUMN "sessionsRevokedAt" TIMESTAMP(3);
|
||||
@@ -56,9 +56,12 @@ model ClientUser {
|
||||
email String @unique
|
||||
passwordHash String
|
||||
name String
|
||||
// admin (the owner: users and terminals) | manager (runs the venue: products, stock, tabs, reminders)
|
||||
// admin (the owner: users and terminals) | manager (runs the venue: products, stock, tabs, reminders) |
|
||||
// superadmin (runs KoolTap itself: every venue, and the admin page)
|
||||
role String @default("manager")
|
||||
createdAt DateTime @default(now())
|
||||
// Access tokens issued before this are refused, so a forced logout applies at once instead of when they expire
|
||||
sessionsRevokedAt DateTime?
|
||||
|
||||
venue Venue @relation(fields: [venueId], references: [id])
|
||||
|
||||
|
||||
@@ -61,6 +61,35 @@ async function main() {
|
||||
});
|
||||
console.log('Created viewer user: viewer@example.com / Viewer123!');
|
||||
|
||||
// Runs KoolTap itself: every venue, and the admin page
|
||||
const superadminHash = await bcrypt.hash('Super123!', 10);
|
||||
await prisma.clientUser.create({
|
||||
data: {
|
||||
id: uuidv4(),
|
||||
venueId,
|
||||
email: 'superadmin@example.com',
|
||||
passwordHash: superadminHash,
|
||||
name: 'KoolTap',
|
||||
role: 'superadmin',
|
||||
},
|
||||
});
|
||||
console.log('Created superadmin user: superadmin@example.com / Super123!');
|
||||
|
||||
// A second venue, so the admin page has more than one
|
||||
const secondVenueId = uuidv4();
|
||||
await prisma.venue.create({ data: { id: secondVenueId, name: 'KoolTap Festival Bar' } });
|
||||
await prisma.clientUser.create({
|
||||
data: {
|
||||
id: uuidv4(),
|
||||
venueId: secondVenueId,
|
||||
email: 'festival@example.com',
|
||||
passwordHash: adminHash,
|
||||
name: 'Festival',
|
||||
role: 'admin',
|
||||
},
|
||||
});
|
||||
console.log('Created venue: KoolTap Festival Bar, admin festival@example.com / Admin123!');
|
||||
|
||||
// Create one device
|
||||
const deviceId = uuidv4();
|
||||
const token = 'dev_' + crypto.randomBytes(48).toString('base64url');
|
||||
@@ -208,6 +237,7 @@ async function main() {
|
||||
console.log('Demo credentials:');
|
||||
console.log(' Admin: admin@example.com / Admin123!');
|
||||
console.log(' Viewer: viewer@example.com / Viewer123!');
|
||||
console.log(' Superadmin: superadmin@example.com / Super123!');
|
||||
console.log(`\nDevice token (for simulator): ${token}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
/**
|
||||
* Makes an existing dashboard user a superadmin, or an admin again with --revoke. There is no other way to become
|
||||
* the first superadmin: the dashboard only lets a superadmin hand out the role.
|
||||
*
|
||||
* pnpm --filter @kooltap/api run superadmin user@example.com [--revoke]
|
||||
*/
|
||||
async function main() {
|
||||
const [email, flag] = process.argv.slice(2);
|
||||
if (!email) {
|
||||
console.error('Usage: superadmin <email> [--revoke]');
|
||||
process.exit(1);
|
||||
}
|
||||
const role = flag === '--revoke' ? 'admin' : 'superadmin';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
try {
|
||||
const user = await prisma.clientUser.findUnique({ where: { email } });
|
||||
if (!user) {
|
||||
console.error(`No user with email ${email}`);
|
||||
process.exit(1);
|
||||
}
|
||||
await prisma.clientUser.update({ where: { id: user.id }, data: { role } });
|
||||
console.log(`${email} is now ${role === 'superadmin' ? 'a superadmin' : 'an admin'}`);
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user