From ae6ea3e1cf9576dd33e4c65830953a72eed24c69 Mon Sep 17 00:00:00 2001 From: alphaeusmote <41258468-alphaeusmote@users.noreply.replit.com> Date: Thu, 10 Apr 2025 02:59:54 +0000 Subject: [PATCH] Add user registration disable toggle and default admin user creation. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 705f2157-ef97-4fbd-89e4-8c7f2ecaea90 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7ed01c5f-a82d-405a-b728-b2e3d127c60c/26934df9-13b2-48c7-b4c5-fdcb1c2c521b.jpg --- server/auth.ts | 59 +++++++++++++++++++++++++++++++++++++++++++++++ server/storage.ts | 20 ++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/server/auth.ts b/server/auth.ts index f7d9df1..6a6034f 100644 --- a/server/auth.ts +++ b/server/auth.ts @@ -21,6 +21,11 @@ declare global { const scryptAsync = promisify(scrypt); const JWT_SECRET = process.env.JWT_SECRET || "super-secret-key-change-in-production"; const SESSION_SECRET = process.env.SESSION_SECRET || "session-secret-change-in-production"; +const DISABLE_REGISTRATION = process.env.DISABLE_REGISTRATION === "true"; +const DEFAULT_ADMIN_USERNAME = process.env.DEFAULT_ADMIN_USERNAME || "admin"; +const DEFAULT_ADMIN_PASSWORD = process.env.DEFAULT_ADMIN_PASSWORD || "password"; +const DEFAULT_ADMIN_EMAIL = process.env.DEFAULT_ADMIN_EMAIL; +const DEFAULT_ADMIN_FULLNAME = process.env.DEFAULT_ADMIN_FULLNAME || "System Administrator"; async function hashPassword(password: string) { const salt = randomBytes(16).toString("hex"); @@ -35,7 +40,56 @@ async function comparePasswords(supplied: string, stored: string) { return timingSafeEqual(hashedBuf, suppliedBuf); } +// Function to initialize default admin user +async function initializeDefaultAdmin() { + try { + // Check if admin user exists + const adminUser = await storage.getUserByUsername(DEFAULT_ADMIN_USERNAME); + + if (!adminUser) { + console.log(`Creating default admin user: ${DEFAULT_ADMIN_USERNAME}`); + + // Get admin role + let adminRole = await storage.getRoleByName("admin"); + + // If no admin role exists, create one with all permissions + if (!adminRole) { + console.log("Creating admin role with all permissions"); + adminRole = await storage.createRole({ + name: "admin", + description: "Administrator role with all permissions", + isDefault: false, + }); + + // Add all permissions to the admin role + const permissions = Object.values(PERMISSIONS); + for (const permission of permissions) { + await storage.addPermissionToRole(adminRole.id, permission); + } + } + + // Create the admin user + const hashedPassword = await hashPassword(DEFAULT_ADMIN_PASSWORD); + await storage.createUser({ + username: DEFAULT_ADMIN_USERNAME, + password: hashedPassword, + email: DEFAULT_ADMIN_EMAIL || null, + fullName: DEFAULT_ADMIN_FULLNAME, + roleId: adminRole.id, + authProvider: "local" + }); + + console.log(`Default admin user created successfully`); + } + } catch (error) { + console.error("Failed to initialize default admin user:", error); + } +} + export function setupAuth(app: Express) { + // Initialize the default admin user + initializeDefaultAdmin(); + const sessionSettings: session.SessionOptions = { secret: SESSION_SECRET, resave: false, @@ -197,6 +251,11 @@ export function setupAuth(app: Express) { // Registration endpoint app.post("/api/register", async (req, res, next) => { try { + // Check if registration is disabled + if (DISABLE_REGISTRATION) { + return res.status(403).json({ message: "User registration is disabled" }); + } + const validationResult = loginSchema.safeParse(req.body); if (!validationResult.success) { return res.status(400).json({ message: "Invalid input", errors: validationResult.error.errors }); diff --git a/server/storage.ts b/server/storage.ts index 8bf3dd6..42d0f12 100644 --- a/server/storage.ts +++ b/server/storage.ts @@ -204,10 +204,30 @@ export class DatabaseStorage implements IStorage { return result.length > 0 ? result[0] : undefined; } + async getRoleByName(name: string): Promise { + const result = await db.select().from(roles).where(eq(roles.name, name)); + return result.length > 0 ? result[0] : undefined; + } + async getDefaultRole(): Promise { const result = await db.select().from(roles).where(eq(roles.isDefault, true)); return result.length > 0 ? result[0] : undefined; } + + async createRole(roleData: { name: string; description?: string; isDefault?: boolean }): Promise { + const result = await db.insert(roles).values(roleData).returning(); + return result[0]; + } + + async addPermissionToRole(roleId: number, permission: string): Promise { + try { + await db.insert(rolePermissions).values({ roleId, permission }).returning(); + return true; + } catch (error) { + console.error('Error adding permission to role:', error); + return false; + } + } // API Token management async getApiToken(id: number): Promise {