nodebb-plugin-calendar-onekite 11.1.14 → 11.1.16

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/lib/admin.js CHANGED
@@ -157,4 +157,66 @@ admin.purgeByYear = async function (req, res) {
157
157
  res.json({ ok: true, removed: count });
158
158
  };
159
159
 
160
+ // Debug endpoint to validate HelloAsso connectivity and item loading
161
+ admin.debugHelloAsso = async function (req, res) {
162
+ const settings = await meta.settings.get('calendar-onekite');
163
+ const env = (settings && settings.helloassoEnv) || 'prod';
164
+
165
+ // Never expose secrets in debug output
166
+ const safeSettings = {
167
+ helloassoEnv: env,
168
+ helloassoClientId: settings && settings.helloassoClientId ? String(settings.helloassoClientId) : '',
169
+ helloassoClientSecret: settings && settings.helloassoClientSecret ? '***' : '',
170
+ helloassoOrganizationSlug: settings && settings.helloassoOrganizationSlug ? String(settings.helloassoOrganizationSlug) : '',
171
+ helloassoFormType: settings && settings.helloassoFormType ? String(settings.helloassoFormType) : '',
172
+ helloassoFormSlug: settings && settings.helloassoFormSlug ? String(settings.helloassoFormSlug) : '',
173
+ };
174
+
175
+ const out = {
176
+ ok: true,
177
+ settings: safeSettings,
178
+ token: { ok: false },
179
+ items: { ok: false, count: 0, sample: [] },
180
+ };
181
+
182
+ try {
183
+ const token = await helloasso.getAccessToken({
184
+ env,
185
+ clientId: settings.helloassoClientId,
186
+ clientSecret: settings.helloassoClientSecret,
187
+ });
188
+ if (!token) {
189
+ out.token = { ok: false, error: 'token-null' };
190
+ return res.json(out);
191
+ }
192
+ out.token = { ok: true };
193
+
194
+ try {
195
+ const items = await helloasso.listItems({
196
+ env,
197
+ token,
198
+ organizationSlug: settings.helloassoOrganizationSlug,
199
+ formType: settings.helloassoFormType,
200
+ formSlug: settings.helloassoFormSlug,
201
+ });
202
+ const arr = Array.isArray(items) ? items : [];
203
+ out.items.ok = true;
204
+ out.items.count = arr.length;
205
+ out.items.sample = arr.slice(0, 10).map((it) => ({
206
+ id: it.id || it.itemId || it.reference || it.name,
207
+ name: it.name || it.label || it.itemName,
208
+ price: it.price || it.amount || it.unitPrice || null,
209
+ }));
210
+ } catch (e) {
211
+ out.items = { ok: false, error: String(e && e.message ? e.message : e), count: 0, sample: [] };
212
+ }
213
+
214
+ return res.json(out);
215
+ } catch (e) {
216
+ out.ok = false;
217
+ out.token = { ok: false, error: String(e && e.message ? e.message : e) };
218
+ return res.json(out);
219
+ }
220
+ };
221
+
160
222
  module.exports = admin;
package/library.js CHANGED
@@ -36,11 +36,11 @@ Plugin.init = async function (params) {
36
36
  );
37
37
 
38
38
  // Admin API (JSON)
39
- const adminMws = mw(
40
- middleware.exposeUid,
41
- middleware.ensureLoggedIn,
42
- middleware.admin && middleware.admin.checkPrivileges
43
- );
39
+ // checkPrivileges() returns a middleware when called with a privilege string.
40
+ const privMw = (middleware.admin && typeof middleware.admin.checkPrivileges === 'function')
41
+ ? middleware.admin.checkPrivileges('admin:settings')
42
+ : null;
43
+ const adminMws = mw(middleware.exposeUid, middleware.ensureLoggedIn, privMw);
44
44
 
45
45
  router.get('/api/v3/admin/plugins/calendar-onekite/settings', adminMws, admin.getSettings);
46
46
  router.put('/api/v3/admin/plugins/calendar-onekite/settings', adminMws, admin.saveSettings);
@@ -51,6 +51,8 @@ Plugin.init = async function (params) {
51
51
 
52
52
  router.post('/api/v3/admin/plugins/calendar-onekite/purge', adminMws, admin.purgeByYear);
53
53
 
54
+ router.get('/api/v3/admin/plugins/calendar-onekite/debug', adminMws, admin.debugHelloAsso);
55
+
54
56
  scheduler.start();
55
57
  };
56
58
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-calendar-onekite",
3
- "version": "11.1.14",
3
+ "version": "11.1.16",
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/public/admin.js CHANGED
@@ -106,6 +106,10 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
106
106
  });
107
107
  }
108
108
 
109
+ async function debugHelloAsso() {
110
+ return await fetchJson('/api/v3/admin/plugins/calendar-onekite/debug');
111
+ }
112
+
109
113
  async function init() {
110
114
  const form = document.getElementById('onekite-settings-form');
111
115
  if (!form) return;
@@ -194,6 +198,27 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
194
198
  });
195
199
  });
196
200
  }
201
+
202
+ // Debug
203
+ const debugBtn = document.getElementById('onekite-debug-run');
204
+ if (debugBtn) {
205
+ debugBtn.addEventListener('click', async () => {
206
+ const out = document.getElementById('onekite-debug-output');
207
+ if (out) out.textContent = 'Chargement...';
208
+ try {
209
+ const result = await debugHelloAsso();
210
+ if (out) out.textContent = JSON.stringify(result, null, 2);
211
+ if (result && result.items && result.items.ok) {
212
+ showAlert('success', `Items HelloAsso: ${result.items.count}`);
213
+ } else {
214
+ showAlert('error', 'HelloAsso: impossible de récupérer les items.');
215
+ }
216
+ } catch (e) {
217
+ if (out) out.textContent = String(e && e.message ? e.message : e);
218
+ showAlert('error', 'Debug impossible.');
219
+ }
220
+ });
221
+ }
197
222
  }
198
223
 
199
224
  return { init };
@@ -1,12 +1,27 @@
1
1
  <!-- IMPORT admin/partials/settings/header.tpl -->
2
2
 
3
3
  <div class="acp-page-container">
4
- <div class="row">
5
- <div class="col-lg-8">
6
- <h2>Calendar OneKite</h2>
7
- <div class="alert alert-info">Paramètres du plugin de calendrier / réservation.</div>
4
+ <h2>Calendar OneKite</h2>
5
+ <div class="alert alert-info">Paramètres du plugin de calendrier / réservation.</div>
8
6
 
9
- <form id="onekite-settings-form">
7
+ <ul class="nav nav-tabs" role="tablist">
8
+ <li class="nav-item" role="presentation">
9
+ <button class="nav-link active" id="onekite-tab-settings" data-bs-toggle="tab" data-bs-target="#onekite-pane-settings" type="button" role="tab">Paramètres</button>
10
+ </li>
11
+ <li class="nav-item" role="presentation">
12
+ <button class="nav-link" id="onekite-tab-pending" data-bs-toggle="tab" data-bs-target="#onekite-pane-pending" type="button" role="tab">Demandes</button>
13
+ </li>
14
+ <li class="nav-item" role="presentation">
15
+ <button class="nav-link" id="onekite-tab-purge" data-bs-toggle="tab" data-bs-target="#onekite-pane-purge" type="button" role="tab">Purge</button>
16
+ </li>
17
+ <li class="nav-item" role="presentation">
18
+ <button class="nav-link" id="onekite-tab-debug" data-bs-toggle="tab" data-bs-target="#onekite-pane-debug" type="button" role="tab">Debug</button>
19
+ </li>
20
+ </ul>
21
+
22
+ <div class="tab-content pt-3">
23
+ <div class="tab-pane fade show active" id="onekite-pane-settings" role="tabpanel" aria-labelledby="onekite-tab-settings">
24
+ <form id="onekite-settings-form" style="max-width: 860px;">
10
25
  <div class="mb-3">
11
26
  <label class="form-label">Groupes autorisés (séparés par virgules)</label>
12
27
  <input class="form-control" name="allowedGroups" placeholder="registered-users, membres">
@@ -54,8 +69,13 @@
54
69
 
55
70
  <button type="button" class="btn btn-primary" id="onekite-save">Enregistrer</button>
56
71
  </form>
72
+ </div>
57
73
 
58
- <hr>
74
+ <div class="tab-pane fade" id="onekite-pane-pending" role="tabpanel" aria-labelledby="onekite-tab-pending">
75
+ <div id="onekite-pending" class="list-group" style="max-width: 860px;"></div>
76
+ </div>
77
+
78
+ <div class="tab-pane fade" id="onekite-pane-purge" role="tabpanel" aria-labelledby="onekite-tab-purge">
59
79
  <h5>Purger</h5>
60
80
  <div class="input-group" style="max-width: 280px;">
61
81
  <input id="onekite-purge-year" class="form-control" placeholder="YYYY" maxlength="4">
@@ -64,9 +84,12 @@
64
84
  <small class="text-muted">Supprime toutes les réservations dont la date de début est dans l'année donnée.</small>
65
85
  </div>
66
86
 
67
- <div class="col-lg-4">
68
- <h5>Demandes en attente</h5>
69
- <div id="onekite-pending" class="list-group"></div>
87
+ <div class="tab-pane fade" id="onekite-pane-debug" role="tabpanel" aria-labelledby="onekite-tab-debug">
88
+ <div class="mb-2">
89
+ <button type="button" class="btn btn-outline-secondary" id="onekite-debug-run">Tester le chargement du matériel (HelloAsso)</button>
90
+ </div>
91
+ <pre id="onekite-debug-output" class="p-2 bg-body-tertiary" style="border-radius: 8px; max-width: 860px; min-height: 160px; overflow:auto;"></pre>
92
+ <small class="text-muted">Affiche l'état du token OAuth2 et un échantillon des items récupérés.</small>
70
93
  </div>
71
94
  </div>
72
95
  </div>