nodebb-plugin-calendar-onekite 12.0.8 → 12.0.9

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/lib/api.js +51 -23
  2. package/package.json +1 -1
package/lib/api.js CHANGED
@@ -17,6 +17,35 @@ async function userInAnyGroup(uid, allowed) {
17
17
  return allowed.some(g => slugs.includes(g));
18
18
  }
19
19
 
20
+
21
+ function normalizeAllowedGroups(raw) {
22
+ if (!raw) return [];
23
+ if (Array.isArray(raw)) return raw.map(v => String(v).trim()).filter(Boolean);
24
+ const s = String(raw).trim();
25
+ if (!s) return [];
26
+ // Some admin UIs store JSON arrays as strings
27
+ if ((s.startsWith('[') && s.endsWith(']')) || (s.startsWith('"[') && s.endsWith(']"'))) {
28
+ try {
29
+ const parsed = JSON.parse(s.startsWith('"') ? JSON.parse(s) : s);
30
+ if (Array.isArray(parsed)) return parsed.map(v => String(v).trim()).filter(Boolean);
31
+ } catch (e) {}
32
+ }
33
+ return s.split(',').map(v => String(v).trim().replace(/^"+|"+$/g, '')).filter(Boolean);
34
+ }
35
+
36
+ async function isMemberOfAnyGroup(uid, allowed) {
37
+ if (!uid || !allowed || !allowed.length) return false;
38
+ for (const g of allowed) {
39
+ try {
40
+ if (await groups.isMember(uid, g)) return true;
41
+ } catch (e) {
42
+ // ignore
43
+ }
44
+ }
45
+ return false;
46
+ }
47
+
48
+
20
49
  const helloasso = require('./helloasso');
21
50
 
22
51
  // Email helper: NodeBB's Emailer signature differs across versions.
@@ -124,17 +153,25 @@ function autoFormSlugForYear(year) {
124
153
  }
125
154
 
126
155
  async function canRequest(uid, settings, startTs) {
156
+ if (!uid) return false;
157
+
158
+ // Always allow administrators to create.
159
+ try {
160
+ if (await groups.isMember(uid, 'administrators')) return true;
161
+ } catch (e) {}
162
+
127
163
  const year = yearFromTs(startTs);
128
164
  const defaultGroup = autoCreatorGroupForYear(year);
129
- const extras = (settings.creatorGroups || settings.allowedGroups || '').split(',').map(s => s.trim()).filter(Boolean);
130
- const allowed = [defaultGroup, ...extras].filter(Boolean);
131
- // If only the default group exists, enforce membership (do not open access to all).
132
- if (!allowed.length) return true;
133
- for (const g of allowed) {
134
- const isMember = await groups.isMember(uid, g);
135
- if (isMember) return true;
136
- }
137
- return false;
165
+
166
+ // ACP may store group slugs as CSV string or array depending on NodeBB/admin UI.
167
+ const raw = settings.creatorGroups ?? settings.allowedGroups ?? [];
168
+ const extraGroups = normalizeAllowedGroups(raw);
169
+
170
+ const allowed = [defaultGroup, ...extraGroups].filter(Boolean);
171
+
172
+ // Enforce membership in at least one allowed group.
173
+ // Use groups.isMember so hidden groups still work.
174
+ return await isMemberOfAnyGroup(uid, allowed);
138
175
  }
139
176
 
140
177
  async function canValidate(uid, settings) {
@@ -142,12 +179,9 @@ async function canValidate(uid, settings) {
142
179
  // even if validatorGroups is empty.
143
180
  try {
144
181
  const isAdmin = await groups.isMember(uid, 'administrators');
145
- if (isAdmin) return true;
146
- const isGlobalMod = await groups.isMember(uid, 'Global Moderators');
147
- if (isGlobalMod) return true;
148
- } catch (e) {}
182
+ if (isAdmin) return true;} catch (e) {}
149
183
 
150
- const allowed = (settings.validatorGroups || '').split(',').map(s => s.trim()).filter(Boolean);
184
+ const allowed = normalizeAllowedGroups(settings.validatorGroups || '');
151
185
  if (!allowed.length) return false;
152
186
  if (await userInAnyGroup(uid, allowed)) return true;
153
187
 
@@ -158,11 +192,8 @@ async function canCreateSpecial(uid, settings) {
158
192
  if (!uid) return false;
159
193
  try {
160
194
  const isAdmin = await groups.isMember(uid, 'administrators');
161
- if (isAdmin) return true;
162
- const isGlobalMod = await groups.isMember(uid, 'Global Moderators');
163
- if (isGlobalMod) return true;
164
- } catch (e) {}
165
- const allowed = (settings.specialCreatorGroups || '').split(',').map(s => s.trim()).filter(Boolean);
195
+ if (isAdmin) return true;} catch (e) {}
196
+ const allowed = normalizeAllowedGroups(settings.specialCreatorGroups || '');
166
197
  if (!allowed.length) return false;
167
198
  if (await userInAnyGroup(uid, allowed)) return true;
168
199
 
@@ -173,10 +204,7 @@ async function canDeleteSpecial(uid, settings) {
173
204
  if (!uid) return false;
174
205
  try {
175
206
  const isAdmin = await groups.isMember(uid, 'administrators');
176
- if (isAdmin) return true;
177
- const isGlobalMod = await groups.isMember(uid, 'Global Moderators');
178
- if (isGlobalMod) return true;
179
- } catch (e) {}
207
+ if (isAdmin) return true;} catch (e) {}
180
208
  const allowed = (settings.specialDeleterGroups || settings.specialCreatorGroups || '').split(',').map(s => s.trim()).filter(Boolean);
181
209
  if (!allowed.length) return false;
182
210
  if (await userInAnyGroup(uid, allowed)) return true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-calendar-onekite",
3
- "version": "12.0.8",
3
+ "version": "12.0.9",
4
4
  "description": "FullCalendar-based equipment reservation workflow with admin approval & HelloAsso payment for NodeBB",
5
5
  "main": "library.js",
6
6
  "license": "MIT",