const path = require("path"); const { PERMISSION_LEVELS, REVIEW_STATES, STATUS_VALUES, VISIBILITY_VALUES, accessForUser, createEntry, ensureTables, getEditableEntry, getEntryBySlug, grantPermission, listEntries, listPermissions, listUsers, listVersions, revokePermission, searchForAi, setEntryWorkflow, updateEntry } = require("./backend/okf_store"); const { renderMarkdown } = require("./backend/markdown"); const PLUGIN_ID = "okf"; module.exports = { id: PLUGIN_ID, init({ web, db }) { ensureTables(db); if (!global.lumiFrameworks) { global.lumiFrameworks = {}; } global.lumiFrameworks.okf = { search: ({ query, user, limit } = {}) => searchForAi(db, query || "", user, limit || 5), accessForUser: (user) => accessForUser(db, user) }; const router = web.createRouter(); router.use((req, res, next) => { res.locals.okfAccess = accessForUser(db, req.session.user); next(); }); router.get("/", requireLogin, (req, res) => { const filters = { q: req.query.q || "", category: req.query.category || "", tag: req.query.tag || "" }; const entries = listEntries(db, filters, req.session.user); res.render(view("index"), { title: "Knowledge", entries, filters, categories: categoriesFor(entries), tags: tagsFor(entries) }); }); router.get("/admin", requireOkfManagement(db), (req, res) => { renderAdmin(req, res, db); }); router.post("/admin/entries", requireOkfEdit(db), (req, res) => { try { const entry = createEntry(db, req.body, req.session.user); req.session.flash = { type: "success", message: "OKF entry created." }; res.redirect(`/plugins/${PLUGIN_ID}/admin?edit=${encodeURIComponent(entry.slug)}`); } catch (error) { req.session.flash = { type: "error", message: error.message }; res.redirect(`/plugins/${PLUGIN_ID}/admin`); } }); router.post("/admin/entries/:slug", requireOkfEdit(db), (req, res) => { try { const entry = updateEntry(db, req.params.slug, req.body, req.session.user); req.session.flash = { type: "success", message: "OKF entry updated." }; res.redirect(`/plugins/${PLUGIN_ID}/admin?edit=${encodeURIComponent(entry.slug)}`); } catch (error) { req.session.flash = { type: "error", message: error.message }; res.redirect(`/plugins/${PLUGIN_ID}/admin?edit=${encodeURIComponent(req.params.slug)}`); } }); router.post("/admin/entries/:slug/:action", requireOkfManagement(db), (req, res) => { try { const entry = setEntryWorkflow(db, req.params.slug, req.params.action, req.session.user, req.body.note || ""); req.session.flash = { type: "success", message: "OKF workflow updated." }; res.redirect(`/plugins/${PLUGIN_ID}/admin?edit=${encodeURIComponent(entry.slug)}`); } catch (error) { req.session.flash = { type: "error", message: error.message }; res.redirect(`/plugins/${PLUGIN_ID}/admin?edit=${encodeURIComponent(req.params.slug)}`); } }); router.post("/admin/permissions", requireAdmin, (req, res) => { try { grantPermission(db, req.body, req.session.user); req.session.flash = { type: "success", message: "OKF permission granted." }; } catch (error) { req.session.flash = { type: "error", message: error.message }; } res.redirect(`/plugins/${PLUGIN_ID}/admin#okf-permissions`); }); router.post("/admin/permissions/:id/revoke", requireAdmin, (req, res) => { try { revokePermission(db, req.params.id, req.session.user); req.session.flash = { type: "success", message: "OKF permission revoked." }; } catch (error) { req.session.flash = { type: "error", message: error.message }; } res.redirect(`/plugins/${PLUGIN_ID}/admin#okf-permissions`); }); router.get("/:slug", requireLogin, (req, res) => { const entry = getEntryBySlug(db, req.params.slug, req.session.user); if (!entry) { return res.status(404).render("error", { title: "Knowledge entry unavailable", message: "That OKF entry was not found or is not visible to your account." }); } res.render(view("entry"), { title: entry.title, entry, renderMarkdown }); }); web.mount(`/plugins/${PLUGIN_ID}`, router, { label: "Knowledge", role: "public", authRequired: true, section: "community", canAccess: (user) => Boolean(user) }); web.addNavItem({ label: "OKF Management", path: `/plugins/${PLUGIN_ID}/admin`, role: "public", authRequired: true, section: "admin", canAccess: (user) => accessForUser(db, user).canEdit }); } }; function renderAdmin(req, res, db) { const filters = { q: req.query.q || "", status: req.query.status || "", category: req.query.category || "", tag: req.query.tag || "" }; const entries = listEntries(db, filters, req.session.user, { management: true }); const selected = req.query.edit ? getEditableEntry(db, req.query.edit) : null; const versions = selected ? listVersions(db, selected.id) : []; res.render(view("admin"), { title: "OKF Management", entries, filters, selected, versions, permissions: listPermissions(db), users: listUsers(db), levels: PERMISSION_LEVELS, statuses: STATUS_VALUES, visibilityValues: VISIBILITY_VALUES, reviewStates: REVIEW_STATES, categories: categoriesFor(entries), tags: tagsFor(entries), renderMarkdown }); } function view(name) { return path.join(__dirname, "views", `${name}.ejs`); } function requireLogin(req, res, next) { if (req.session.user) return next(); return res.redirect("/login"); } function requireAdmin(req, res, next) { if (req.session.user?.isAdmin) return next(); return denied(res); } function requireOkfManagement(db) { return (req, res, next) => { if (accessForUser(db, req.session.user).canEdit) return next(); return denied(res); }; } function requireOkfEdit(db) { return (req, res, next) => { if (accessForUser(db, req.session.user).canEdit) return next(); return denied(res); }; } function denied(res) { return res.status(403).render("error", { title: "Access denied", message: "You do not have access to that page." }); } function categoriesFor(entries) { return Array.from(new Set(entries.map((entry) => entry.category).filter(Boolean))).sort(); } function tagsFor(entries) { return Array.from(new Set(entries.flatMap((entry) => entry.tags || []).filter(Boolean))).sort(); }