"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var admin_exports = {}; __export(admin_exports, { adminListPreviews: () => adminListPreviews, adminStopPreview: () => adminStopPreview, createUser: () => createUser, deleteUser: () => deleteUser, getSettings: () => getSettings, listUsers: () => listUsers, updateSettings: () => updateSettings, updateUser: () => updateUser }); module.exports = __toCommonJS(admin_exports); var import_bcryptjs = __toESM(require("bcryptjs")); var import_db = require("../../lib/db"); var import_response = require("../../lib/response"); var import_errors = require("../../lib/errors"); var import_adminSettings = require("../../lib/adminSettings"); function requireAdmin(ctr) { const auth = ctr.getAuth?.(); if (!auth?.success) return null; if (!auth.user.isAdmin) return null; return auth.user; } async function listUsers(ctr) { const admin = requireAdmin(ctr); if (!admin) return (0, import_response.makeResponse)({ ctr, content: { code: 403, message: import_errors.ERROR_MESSAGES.FORBIDDEN.message } }); const users = await import_db.prisma.user.findMany({ select: { id: true, username: true, isAdmin: true, isFounder: true, createdAt: true, giteaInstanceUrl: true }, orderBy: { createdAt: "asc" } }); return (0, import_response.makeResponse)({ ctr, content: { code: 200, data: users } }); } async function createUser(ctr) { const admin = requireAdmin(ctr); if (!admin) return (0, import_response.makeResponse)({ ctr, content: { code: 403, message: import_errors.ERROR_MESSAGES.FORBIDDEN.message } }); const body = await ctr.body(); const { username, password } = body || {}; if (!username || !password) return (0, import_response.makeResponse)({ ctr, content: { code: 400, message: "Username and password required" } }); const existing = await import_db.prisma.user.findUnique({ where: { username } }); if (existing) return (0, import_response.makeResponse)({ ctr, content: { code: 409, message: "Username already taken" } }); const userCount = await import_db.prisma.user.count(); const isFirst = userCount === 0; const hash = await import_bcryptjs.default.hash(password, 12); const user = await import_db.prisma.user.create({ data: { username, passwordHash: hash, isAdmin: isFirst, isFounder: isFirst }, select: { id: true, username: true, isAdmin: true, isFounder: true } }); return (0, import_response.makeResponse)({ ctr, content: { code: 201, data: user } }); } async function updateUser(ctr) { const admin = requireAdmin(ctr); if (!admin) return (0, import_response.makeResponse)({ ctr, content: { code: 403, message: import_errors.ERROR_MESSAGES.FORBIDDEN.message } }); const id = parseInt(ctr.params.get("id") || "0", 10); const target = await import_db.prisma.user.findUnique({ where: { id } }); if (!target) return (0, import_response.makeResponse)({ ctr, content: { code: 404, message: import_errors.ERROR_MESSAGES.NOT_FOUND.message } }); const body = await ctr.body(); const { username, password, isAdmin } = body || {}; const data = {}; if (username) { const existing = await import_db.prisma.user.findFirst({ where: { username, id: { not: id } } }); if (existing) return (0, import_response.makeResponse)({ ctr, content: { code: 409, message: "Username taken" } }); data.username = username; } if (password) data.passwordHash = await import_bcryptjs.default.hash(password, 12); if (isAdmin !== void 0 && !target.isFounder) data.isAdmin = Boolean(isAdmin); await import_db.prisma.user.update({ where: { id }, data }); return (0, import_response.makeResponse)({ ctr, content: { code: 200, message: "User updated" } }); } async function deleteUser(ctr) { const admin = requireAdmin(ctr); if (!admin) return (0, import_response.makeResponse)({ ctr, content: { code: 403, message: import_errors.ERROR_MESSAGES.FORBIDDEN.message } }); const id = parseInt(ctr.params.get("id") || "0", 10); const target = await import_db.prisma.user.findUnique({ where: { id } }); if (!target) return (0, import_response.makeResponse)({ ctr, content: { code: 404, message: import_errors.ERROR_MESSAGES.NOT_FOUND.message } }); if (target.isFounder) return (0, import_response.makeResponse)({ ctr, content: { code: 403, message: "Cannot delete founder" } }); if (id === admin.id) return (0, import_response.makeResponse)({ ctr, content: { code: 403, message: "Cannot delete yourself" } }); await import_db.prisma.user.delete({ where: { id } }); return (0, import_response.makeResponse)({ ctr, content: { code: 200, message: "User deleted" } }); } async function getSettings(ctr) { const admin = requireAdmin(ctr); if (!admin) return (0, import_response.makeResponse)({ ctr, content: { code: 403, message: import_errors.ERROR_MESSAGES.FORBIDDEN.message } }); const settings = await (0, import_adminSettings.getAdminSettings)(); return (0, import_response.makeResponse)({ ctr, content: { code: 200, data: settings } }); } async function updateSettings(ctr) { const admin = requireAdmin(ctr); if (!admin) return (0, import_response.makeResponse)({ ctr, content: { code: 403, message: import_errors.ERROR_MESSAGES.FORBIDDEN.message } }); const body = await ctr.body(); const { defaultInstanceType, maxConcurrentInstancesPerUser, logSizeLimitBytes, previewRetentionDays, webhookRateLimitPerMinute, contactEmail } = body || {}; const data = {}; if (defaultInstanceType) data.defaultInstanceType = defaultInstanceType; if (maxConcurrentInstancesPerUser) data.maxConcurrentInstancesPerUser = Number(maxConcurrentInstancesPerUser); if (logSizeLimitBytes) data.logSizeLimitBytes = Number(logSizeLimitBytes); if (previewRetentionDays) data.previewRetentionDays = Number(previewRetentionDays); if (webhookRateLimitPerMinute) data.webhookRateLimitPerMinute = Number(webhookRateLimitPerMinute); if (contactEmail !== void 0) data.contactEmail = contactEmail; await import_db.prisma.adminSettings.upsert({ where: { id: 1 }, update: data, create: { id: 1, ...data } }); return (0, import_response.makeResponse)({ ctr, content: { code: 200, message: "Settings updated" } }); } async function adminListPreviews(ctr) { const admin = requireAdmin(ctr); if (!admin) return (0, import_response.makeResponse)({ ctr, content: { code: 403, message: import_errors.ERROR_MESSAGES.FORBIDDEN.message } }); const previews = await import_db.prisma.preview.findMany({ include: { repoConfig: { include: { user: { select: { id: true, username: true } } } } }, orderBy: { updatedAt: "desc" }, take: 200 }); return (0, import_response.makeResponse)({ ctr, content: { code: 200, data: previews.map((p) => ({ id: p.id, prNumber: p.prNumber, prTitle: p.prTitle, status: p.status, instanceIp: p.instanceIp, port: p.port, createdAt: p.createdAt, updatedAt: p.updatedAt, repoOwner: p.repoConfig.repoOwner, repoName: p.repoConfig.repoName, user: p.repoConfig.user })) } }); } async function adminStopPreview(ctr) { const admin = requireAdmin(ctr); if (!admin) return (0, import_response.makeResponse)({ ctr, content: { code: 403, message: import_errors.ERROR_MESSAGES.FORBIDDEN.message } }); const id = parseInt(ctr.params.get("id") || "0", 10); const preview = await import_db.prisma.preview.findUnique({ where: { id } }); if (!preview) return (0, import_response.makeResponse)({ ctr, content: { code: 404, message: import_errors.ERROR_MESSAGES.NOT_FOUND.message } }); await import_db.prisma.job.create({ data: { previewId: id, type: "STOP", status: "PENDING", payload: { reason: "Admin stop" } } }); return (0, import_response.makeResponse)({ ctr, content: { code: 200, message: "Stop job enqueued" } }); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { adminListPreviews, adminStopPreview, createUser, deleteUser, getSettings, listUsers, updateSettings, updateUser }); //# sourceMappingURL=admin.js.map