nodebb-plugin-onekite-calendar 2.0.39 → 2.0.40

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 2.0.38
2
+ - Refactor : factorisation du code client (helpers headers/CSRF) et simplification du widget.
3
+ - Widget : suppression des fallbacks de polling/visibilitychange (mise à jour via sockets uniquement) + conservation du no-cache pour éviter les 304.
4
+
1
5
  ## 2.0.37
2
6
  - Les rappels validateurs et notifications d’expiration ne sont envoyés qu’aux membres du/des groupe(s) "personnes notifiées" (notifyGroups).
3
7
 
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ const groups = require.main.require('./src/groups');
4
+
5
+ async function getGroupNameBySlug(slug) {
6
+ const fn = groups && groups.getGroupNameByGroupSlug;
7
+ if (typeof fn !== 'function') return null;
8
+
9
+ const id = String(slug || '').trim();
10
+ if (!id) return null;
11
+
12
+ try {
13
+ const maybe = fn(id);
14
+ if (maybe && typeof maybe.then === 'function') {
15
+ return await maybe;
16
+ }
17
+ if (typeof maybe === 'string') {
18
+ return maybe;
19
+ }
20
+ } catch (e) {
21
+ // fall through to callback form
22
+ }
23
+
24
+ return await new Promise((resolve) => {
25
+ try {
26
+ fn(id, (err, name) => resolve(err ? null : name));
27
+ } catch (e) {
28
+ resolve(null);
29
+ }
30
+ });
31
+ }
package/lib/realtime.js CHANGED
@@ -24,10 +24,6 @@ function emitCalendarUpdated(payload) {
24
24
 
25
25
  // New event name (generic).
26
26
  server.sockets.emit('event:calendar-onekite.calendarUpdated', payload || {});
27
-
28
- // Backwards compatible event name (older clients only listened to this).
29
- // Keep it emitted for *any* calendar mutation, not just reservation status.
30
- server.sockets.emit('event:calendar-onekite.reservationUpdated', payload || {});
31
27
  } catch (e) {}
32
28
  }
33
29
 
package/lib/widgets.js CHANGED
@@ -392,19 +392,19 @@ dateClick: function() { window.location.href = calUrl; },
392
392
  calendar.render();
393
393
 
394
394
  // Real-time refresh for the widget (same server events as the main calendar)
395
+ // We intentionally rely on sockets only (no periodic polling fallback):
396
+ // - keeps the widget lightweight
397
+ // - avoids pointless API traffic
398
+ // - updates are already broadcast server-side across NodeBB instances
395
399
  try {
396
400
  // Debounce per widget instance
397
401
  let tRefetch = null;
398
402
  const refetch = function () {
399
- try {
400
- if (tRefetch) return;
401
- tRefetch = setTimeout(() => {
402
- tRefetch = null;
403
- try {
404
- calendar.refetchEvents();
405
- } catch (e) {}
406
- }, 200);
407
- } catch (e) {}
403
+ if (tRefetch) return;
404
+ tRefetch = setTimeout(() => {
405
+ tRefetch = null;
406
+ try { calendar.refetchEvents(); } catch (e) {}
407
+ }, 200);
408
408
  };
409
409
 
410
410
  // Register refetcher and bind socket listeners once per page
@@ -414,34 +414,15 @@ dateClick: function() { window.location.href = calUrl; },
414
414
  if (!window.__oneKiteWidgetSocketBound && typeof socket !== 'undefined' && socket && typeof socket.on === 'function') {
415
415
  window.__oneKiteWidgetSocketBound = true;
416
416
  const triggerAll = function () {
417
- try {
418
- const list = window.__oneKiteWidgetRefetchers || [];
419
- for (let i = 0; i < list.length; i += 1) {
420
- try { list[i](); } catch (e) {}
421
- }
422
- } catch (e) {}
417
+ const list = window.__oneKiteWidgetRefetchers || [];
418
+ for (let i = 0; i < list.length; i += 1) {
419
+ try { list[i](); } catch (e) {}
420
+ }
423
421
  };
424
422
  socket.on('event:calendar-onekite.calendarUpdated', triggerAll);
425
- socket.on('event:calendar-onekite.reservationUpdated', triggerAll);
426
423
  }
427
424
  } catch (e) {}
428
425
 
429
- // Fallback refresh: in case sockets are unavailable or blocked by proxies,
430
- // refetch periodically and when the tab becomes visible.
431
- try {
432
- window.__oneKiteWidgetIntervals = window.__oneKiteWidgetIntervals || {};
433
- if (!window.__oneKiteWidgetIntervals[containerId]) {
434
- window.__oneKiteWidgetIntervals[containerId] = setInterval(() => {
435
- try { calendar.refetchEvents(); } catch (e) {}
436
- }, 60000);
437
- }
438
- document.addEventListener('visibilitychange', () => {
439
- try {
440
- if (!document.hidden) calendar.refetchEvents();
441
- } catch (e) {}
442
- }, { passive: true });
443
- } catch (e) {}
444
-
445
426
  // Mobile swipe (left/right) to navigate weeks
446
427
  try {
447
428
  let touchStartX = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-onekite-calendar",
3
- "version": "2.0.39",
3
+ "version": "2.0.40",
4
4
  "description": "FullCalendar-based equipment reservation workflow with admin approval & HelloAsso payment for NodeBB",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
package/plugin.json CHANGED
@@ -39,5 +39,5 @@
39
39
  "acpScripts": [
40
40
  "public/admin.js"
41
41
  ],
42
- "version": "2.0.39"
42
+ "version": "2.0.40"
43
43
  }
package/public/admin.js CHANGED
@@ -109,48 +109,32 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
109
109
  }
110
110
 
111
111
  async function fetchJson(url, opts) {
112
- const res = await fetch(url, {
113
- credentials: 'same-origin',
114
- headers: (() => {
115
- const headers = { 'Content-Type': 'application/json' };
116
- const token =
112
+ const getCsrfToken = () => {
113
+ try {
114
+ return (
117
115
  (window.config && (window.config.csrf_token || window.config.csrfToken)) ||
118
116
  (window.ajaxify && window.ajaxify.data && window.ajaxify.data.csrf_token) ||
119
117
  (document.querySelector('meta[name="csrf-token"]') && document.querySelector('meta[name="csrf-token"]').getAttribute('content')) ||
120
118
  (document.querySelector('meta[name="csrf_token"]') && document.querySelector('meta[name="csrf_token"]').getAttribute('content')) ||
121
119
  (typeof app !== 'undefined' && app && app.csrfToken) ||
122
- null;
123
- if (token) headers['x-csrf-token'] = token;
124
- return headers;
125
- })(),
120
+ null
121
+ );
122
+ } catch (e) {
123
+ return null;
124
+ }
125
+ };
126
+
127
+ const headers = { 'Content-Type': 'application/json' };
128
+ const token = getCsrfToken();
129
+ if (token) headers['x-csrf-token'] = token;
130
+
131
+ const res = await fetch(url, {
132
+ credentials: 'same-origin',
133
+ headers,
126
134
  ...opts,
127
135
  });
128
136
 
129
-
130
137
  if (!res.ok) {
131
- // NodeBB versions differ: some expose admin APIs under /api/admin instead of /api/v3/admin
132
- if (res.status === 404 && typeof url === 'string' && url.includes('/api/v3/admin/')) {
133
- const altUrl = url.replace('/api/v3/admin/', '/api/admin/');
134
- const res2 = await fetch(altUrl, {
135
- credentials: 'same-origin',
136
- headers: (() => {
137
- const headers = { 'Content-Type': 'application/json' };
138
- const token =
139
- (window.config && (window.config.csrf_token || window.config.csrfToken)) ||
140
- (window.ajaxify && window.ajaxify.data && window.ajaxify.data.csrf_token) ||
141
- (document.querySelector('meta[name="csrf-token"]') && document.querySelector('meta[name="csrf-token"]').getAttribute('content')) ||
142
- (document.querySelector('meta[name="csrf_token"]') && document.querySelector('meta[name="csrf_token"]').getAttribute('content')) ||
143
- (typeof app !== 'undefined' && app && app.csrfToken) ||
144
- null;
145
- if (token) headers['x-csrf-token'] = token;
146
- return headers;
147
- })(),
148
- ...opts,
149
- });
150
- if (res2.ok) {
151
- return await res2.json();
152
- }
153
- }
154
138
  const text = await res.text().catch(() => '');
155
139
  throw new Error(`${res.status} ${text}`);
156
140
  }
package/public/client.js CHANGED
@@ -138,6 +138,28 @@ define('forum/calendar-onekite', ['alerts', 'bootbox', 'hooks'], function (alert
138
138
  .replace(/'/g, '&#39;');
139
139
  }
140
140
 
141
+ function getCsrfToken() {
142
+ try {
143
+ return (
144
+ (window.config && (window.config.csrf_token || window.config.csrfToken)) ||
145
+ (window.ajaxify && window.ajaxify.data && window.ajaxify.data.csrf_token) ||
146
+ (document.querySelector('meta[name="csrf-token"]') && document.querySelector('meta[name="csrf-token"]').getAttribute('content')) ||
147
+ (document.querySelector('meta[name="csrf_token"]') && document.querySelector('meta[name="csrf_token"]').getAttribute('content')) ||
148
+ (typeof app !== 'undefined' && app && app.csrfToken) ||
149
+ null
150
+ );
151
+ } catch (e) {
152
+ return null;
153
+ }
154
+ }
155
+
156
+ function jsonHeaders(extra) {
157
+ const headers = Object.assign({ 'Content-Type': 'application/json' }, extra || {});
158
+ const token = getCsrfToken();
159
+ if (token) headers['x-csrf-token'] = token;
160
+ return headers;
161
+ }
162
+
141
163
  function pad2(n) { return String(n).padStart(2, '0'); }
142
164
 
143
165
  function toDateInputValue(d) {
@@ -502,18 +524,7 @@ define('forum/calendar-onekite', ['alerts', 'bootbox', 'hooks'], function (alert
502
524
  async function fetchJson(url, opts) {
503
525
  const res = await fetch(url, {
504
526
  credentials: 'same-origin',
505
- headers: (() => {
506
- const headers = { 'Content-Type': 'application/json' };
507
- const token =
508
- (window.config && (window.config.csrf_token || window.config.csrfToken)) ||
509
- (window.ajaxify && window.ajaxify.data && window.ajaxify.data.csrf_token) ||
510
- (document.querySelector('meta[name="csrf-token"]') && document.querySelector('meta[name="csrf-token"]').getAttribute('content')) ||
511
- (document.querySelector('meta[name="csrf_token"]') && document.querySelector('meta[name="csrf_token"]').getAttribute('content')) ||
512
- (typeof app !== 'undefined' && app && app.csrfToken) ||
513
- null;
514
- if (token) headers['x-csrf-token'] = token;
515
- return headers;
516
- })(),
527
+ headers: jsonHeaders((opts && opts.headers) || {}),
517
528
  ...opts,
518
529
  });
519
530
  if (!res.ok) {
@@ -563,19 +574,7 @@ define('forum/calendar-onekite', ['alerts', 'bootbox', 'hooks'], function (alert
563
574
  try {
564
575
  res = await fetch(url, {
565
576
  credentials: 'same-origin',
566
- headers: (() => {
567
- // reuse csrf header builder (fetchJson) by calling it indirectly
568
- const base = { 'Content-Type': 'application/json' };
569
- const token =
570
- (window.config && (window.config.csrf_token || window.config.csrfToken)) ||
571
- (window.ajaxify && window.ajaxify.data && window.ajaxify.data.csrf_token) ||
572
- (document.querySelector('meta[name="csrf-token"]') && document.querySelector('meta[name="csrf-token"]').getAttribute('content')) ||
573
- (document.querySelector('meta[name="csrf_token"]') && document.querySelector('meta[name="csrf_token"]').getAttribute('content')) ||
574
- (typeof app !== 'undefined' && app && app.csrfToken) ||
575
- null;
576
- if (token) base['x-csrf-token'] = token;
577
- return Object.assign(base, headers);
578
- })(),
577
+ headers: jsonHeaders(headers),
579
578
  ...opts,
580
579
  });
581
580
  } catch (e) {
@@ -2383,12 +2382,6 @@ try {
2383
2382
  scheduleRefetch(cal);
2384
2383
  } catch (e) {}
2385
2384
  });
2386
- socket.on('event:calendar-onekite.reservationUpdated', function () {
2387
- try {
2388
- const cal = window.oneKiteCalendar;
2389
- scheduleRefetch(cal);
2390
- } catch (e) {}
2391
- });
2392
2385
  }
2393
2386
  } catch (e) {}
2394
2387