nodebb-plugin-calendar-onekite 11.1.19 → 11.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/library.js +61 -48
  2. package/package.json +2 -2
package/library.js CHANGED
@@ -1,72 +1,85 @@
1
1
  'use strict';
2
2
 
3
+ // We use NodeBB's route helpers for page routes so the rendered page includes
4
+ // the normal client bundle (ajaxify/requirejs). The helper signatures differ
5
+ // across NodeBB versions, but for NodeBB v4.x the order is:
6
+ // setupPageRoute(router, path, middlewaresArray, handler)
7
+ // setupAdminPageRoute(router, path, middlewaresArray, handler)
8
+ const routeHelpers = require.main.require('./src/routes/helpers');
9
+
3
10
  const controllers = require('./lib/controllers');
4
11
  const api = require('./lib/api');
5
12
  const admin = require('./lib/admin');
6
13
  const scheduler = require('./lib/scheduler');
7
14
 
8
- const Groups = require.main.require('./src/groups');
9
-
10
15
  const Plugin = {};
11
16
 
12
- function isFn(fn) { return typeof fn === 'function'; }
13
- function mw(...fns) { return fns.filter(isFn); }
17
+ const isFn = (fn) => typeof fn === 'function';
18
+ const mw = (...fns) => fns.filter(isFn);
14
19
 
15
- // Simple admin guard that does not rely on middleware.admin.checkPrivileges (signature differs across versions)
16
- async function adminGuard(req, res, next) {
17
- try {
18
- if (!req.uid) {
19
- return res.status(403).json({ status: { code: 'forbidden', message: 'Admin only' } });
20
- }
21
- const isAdmin = await Groups.isMember(req.uid, 'administrators');
22
- if (!isAdmin) {
23
- return res.status(403).json({ status: { code: 'forbidden', message: 'Admin only' } });
20
+ Plugin.init = async function (params) {
21
+ const { router, middleware } = params;
22
+
23
+ // Build middleware arrays safely and always spread them into Express route methods.
24
+ // Express will throw if any callback is undefined, so we filter strictly.
25
+ const publicExpose = mw(middleware && middleware.exposeUid);
26
+ const publicAuth = mw(middleware && middleware.exposeUid, middleware && middleware.ensureLoggedIn);
27
+
28
+ // Robust admin guard: avoid middleware.admin.checkPrivileges() signature differences
29
+ // across NodeBB versions. We treat membership in the 'administrators' group as admin.
30
+ const Groups = require.main.require('./src/groups');
31
+ async function adminOnly(req, res, next) {
32
+ try {
33
+ const uid = req.uid;
34
+ if (!uid) {
35
+ return res.status(401).json({ status: { code: 'not-authorized', message: 'Not logged in' } });
36
+ }
37
+ const isAdmin = await Groups.isMember(uid, 'administrators');
38
+ if (!isAdmin) {
39
+ return res.status(403).json({ status: { code: 'not-authorized', message: 'Not allowed' } });
40
+ }
41
+ return next();
42
+ } catch (err) {
43
+ return next(err);
24
44
  }
25
- return next();
26
- } catch (err) {
27
- return next(err);
28
45
  }
29
- }
30
-
31
- Plugin.init = async function (params) {
32
- const router = params.router;
33
- const middleware = params.middleware;
46
+ const adminMws = mw(middleware && middleware.exposeUid, middleware && middleware.ensureLoggedIn, adminOnly);
34
47
 
35
- // ---------- Pages ----------
36
- // Public calendar page
37
- router.get('/calendar', ...mw(middleware.exposeUid, middleware.buildHeader), controllers.renderCalendar);
48
+ // Page routes (HTML)
49
+ // IMPORTANT: pass an ARRAY for middlewares (even if empty), otherwise
50
+ // setupPageRoute will throw "middlewares is not iterable".
51
+ routeHelpers.setupPageRoute(router, '/calendar', mw(), controllers.renderCalendar);
52
+ routeHelpers.setupAdminPageRoute(router, '/admin/plugins/calendar-onekite', mw(), admin.renderAdmin);
38
53
 
39
- // ACP page
40
- router.get('/admin/plugins/calendar-onekite', ...mw(middleware.exposeUid, middleware.admin?.buildHeader), controllers.renderAdmin);
54
+ // Public API (JSON)
55
+ // We register both v3 and legacy (/api/...) endpoints as a compatibility fallback.
41
56
 
42
- // ---------- Public API (v3 + legacy fallback) ----------
43
- const expose = mw(middleware.exposeUid);
57
+ ['/api/v3/plugins/calendar-onekite/events', '/api/plugins/calendar-onekite/events'].forEach((p) => {
58
+ router.get(p, ...publicExpose, api.getEvents);
59
+ });
44
60
 
45
- router.get('/api/v3/plugins/calendar-onekite/events', ...expose, api.getEvents);
46
- router.get('/api/v3/plugins/calendar-onekite/items', ...expose, api.getItems);
47
- router.post('/api/v3/plugins/calendar-onekite/reservations', ...mw(middleware.exposeUid, middleware.ensureLoggedIn), api.createReservation);
61
+ ['/api/v3/plugins/calendar-onekite/items', '/api/plugins/calendar-onekite/items'].forEach((p) => {
62
+ router.get(p, ...publicExpose, api.getItems);
63
+ });
48
64
 
49
- router.get('/api/plugins/calendar-onekite/events', ...expose, api.getEvents);
50
- router.get('/api/plugins/calendar-onekite/items', ...expose, api.getItems);
51
- router.post('/api/plugins/calendar-onekite/reservations', ...mw(middleware.exposeUid, middleware.ensureLoggedIn), api.createReservation);
65
+ ['/api/v3/plugins/calendar-onekite/reservations', '/api/plugins/calendar-onekite/reservations'].forEach((p) => {
66
+ router.post(p, ...publicAuth, api.createReservation);
67
+ });
52
68
 
53
- // ---------- Admin API (v3 + legacy fallback) ----------
54
- const adminMws = mw(middleware.exposeUid, adminGuard);
69
+ // Admin API (JSON)
70
+ const adminBases = ['/api/v3/admin/plugins/calendar-onekite', '/api/admin/plugins/calendar-onekite'];
55
71
 
56
- const adminRoutes = (prefix) => {
57
- router.get(`${prefix}/settings`, ...adminMws, admin.getSettings);
58
- router.put(`${prefix}/settings`, ...adminMws, admin.saveSettings);
59
- router.get(`${prefix}/pending`, ...adminMws, admin.listPending);
60
- router.post(`${prefix}/approve`, ...adminMws, admin.approveReservation);
61
- router.post(`${prefix}/refuse`, ...adminMws, admin.refuseReservation);
62
- router.post(`${prefix}/purge`, ...adminMws, admin.purgeYear);
63
- router.get(`${prefix}/debug`, ...adminMws, admin.debugHelloAsso);
64
- };
72
+ adminBases.forEach((base) => {
73
+ router.get(`${base}/settings`, ...adminMws, admin.getSettings);
74
+ router.put(`${base}/settings`, ...adminMws, admin.saveSettings);
65
75
 
66
- adminRoutes('/api/v3/admin/plugins/calendar-onekite');
67
- adminRoutes('/api/admin/plugins/calendar-onekite');
76
+ router.get(`${base}/pending`, ...adminMws, admin.listPending);
77
+ router.put(`${base}/reservations/:rid/approve`, ...adminMws, admin.approveReservation);
78
+ router.put(`${base}/reservations/:rid/refuse`, ...adminMws, admin.refuseReservation);
68
79
 
69
- // Start periodic cleanup of expired pending reservations
80
+ router.post(`${base}/purge`, ...adminMws, admin.purgeByYear);
81
+ router.get(`${base}/debug`, ...adminMws, admin.debugHelloAsso);
82
+ });
70
83
  scheduler.start();
71
84
  };
72
85
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-calendar-onekite",
3
- "version": "11.1.19",
3
+ "version": "11.1.20",
4
4
  "description": "FullCalendar-based equipment reservation workflow with admin approval & HelloAsso payment for NodeBB",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
@@ -8,4 +8,4 @@
8
8
  "node": ">=18"
9
9
  },
10
10
  "dependencies": {}
11
- }
11
+ }