nodebb-plugin-onekite-calendar 2.0.60 → 2.0.62
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/api.js +23 -3
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/public/client.js +8 -4
- package/nodebb-plugin-onekite-calendar-2.0.40.tgz +0 -0
package/lib/api.js
CHANGED
|
@@ -420,6 +420,26 @@ async function canCreateSpecial(uid, settings) {
|
|
|
420
420
|
return false;
|
|
421
421
|
}
|
|
422
422
|
|
|
423
|
+
|
|
424
|
+
async function canJoinSpecial(uid, settings) {
|
|
425
|
+
if (!uid) return false;
|
|
426
|
+
// Admins always allowed
|
|
427
|
+
try {
|
|
428
|
+
const isAdmin = await groups.isMember(uid, 'administrators');
|
|
429
|
+
if (isAdmin) return true;
|
|
430
|
+
} catch (e) {}
|
|
431
|
+
|
|
432
|
+
// Special-event creators can join/leave
|
|
433
|
+
if (await canCreateSpecial(uid, settings)) return true;
|
|
434
|
+
|
|
435
|
+
// Location creator groups can also participate (even if they can't create events)
|
|
436
|
+
const allowed = normalizeAllowedGroups(settings.creatorGroups || '');
|
|
437
|
+
if (!allowed.length) return false;
|
|
438
|
+
return userInAnyGroup(uid, allowed);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
|
|
423
443
|
async function canDeleteSpecial(uid, settings) {
|
|
424
444
|
if (!uid) return false;
|
|
425
445
|
try {
|
|
@@ -958,7 +978,7 @@ api.getSpecialEventDetails = async function (req, res) {
|
|
|
958
978
|
participants,
|
|
959
979
|
participantsUsernames: await usernamesByUids(participants),
|
|
960
980
|
canDeleteSpecial: canSpecialDelete,
|
|
961
|
-
canJoin: uid ? await
|
|
981
|
+
canJoin: uid ? await canJoinSpecial(uid, settings) : false,
|
|
962
982
|
isParticipant: uid ? participants.includes(String(uid)) : false,
|
|
963
983
|
icsUrl: links.icsUrl,
|
|
964
984
|
googleCalUrl: links.googleCalUrl,
|
|
@@ -973,7 +993,7 @@ api.joinSpecialEvent = async function (req, res) {
|
|
|
973
993
|
const settings = await getSettings();
|
|
974
994
|
const uid = req.uid;
|
|
975
995
|
if (!uid) return res.status(401).json({ error: 'not-logged-in' });
|
|
976
|
-
const ok = await
|
|
996
|
+
const ok = await canJoinSpecial(uid, settings);
|
|
977
997
|
if (!ok) return res.status(403).json({ error: 'not-allowed' });
|
|
978
998
|
|
|
979
999
|
const eid = String(req.params.eid || '').replace(/^special:/, '').trim();
|
|
@@ -1000,7 +1020,7 @@ api.leaveSpecialEvent = async function (req, res) {
|
|
|
1000
1020
|
const settings = await getSettings();
|
|
1001
1021
|
const uid = req.uid;
|
|
1002
1022
|
if (!uid) return res.status(401).json({ error: 'not-logged-in' });
|
|
1003
|
-
const ok = await
|
|
1023
|
+
const ok = await canJoinSpecial(uid, settings);
|
|
1004
1024
|
if (!ok) return res.status(403).json({ error: 'not-allowed' });
|
|
1005
1025
|
|
|
1006
1026
|
const eid = String(req.params.eid || '').replace(/^special:/, '').trim();
|
package/package.json
CHANGED
package/plugin.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1676,11 +1676,14 @@ function toDatetimeLocalValue(date) {
|
|
|
1676
1676
|
const notes = String(p.notes || '').trim();
|
|
1677
1677
|
const participants = Array.isArray(p.participantsUsernames) ? p.participantsUsernames : [];
|
|
1678
1678
|
const eidPlain = escapeHtml(String(p.eid || '').replace(/^special:/, ''));
|
|
1679
|
+
// Participants can self-join/leave if they belong to the allowed group.
|
|
1680
|
+
// Use page capabilities as a fallback (details may be minimal in some edge cases).
|
|
1681
|
+
const canJoinHere = !!(p.canJoin || canCreateSpecial);
|
|
1679
1682
|
// Use real buttons with visible + / - text to avoid relying on icon fonts.
|
|
1680
|
-
const joinBtn = (
|
|
1683
|
+
const joinBtn = (canJoinHere && !p.isParticipant)
|
|
1681
1684
|
? `<button type="button" class="btn btn-sm btn-success ms-2 onekite-join-special" data-eid="${eidPlain}" title="S'ajouter" aria-label="S'ajouter">+</button>`
|
|
1682
1685
|
: '';
|
|
1683
|
-
const leaveBtn = (
|
|
1686
|
+
const leaveBtn = (canJoinHere && p.isParticipant)
|
|
1684
1687
|
? `<button type="button" class="btn btn-sm btn-danger ms-2 onekite-leave-special" data-eid="${eidPlain}" title="Se retirer" aria-label="Se retirer">−</button>`
|
|
1685
1688
|
: '';
|
|
1686
1689
|
const participantsHtml = `<div class="mb-2" id="onekite-participants-special"><strong>Participants</strong>${joinBtn}${leaveBtn}<br>` +
|
|
@@ -1819,10 +1822,11 @@ function toDatetimeLocalValue(date) {
|
|
|
1819
1822
|
const participants = Array.isArray(p.participantsUsernames) ? p.participantsUsernames : [];
|
|
1820
1823
|
const oidPlain = escapeHtml(String(p.oid || '').replace(/^outing:/, ''));
|
|
1821
1824
|
// Use real buttons with visible + / - text to avoid relying on icon fonts.
|
|
1822
|
-
const
|
|
1825
|
+
const canJoinHere = !!(p.canJoin || canCreateOuting);
|
|
1826
|
+
const joinBtn = (canJoinHere && !p.isParticipant)
|
|
1823
1827
|
? `<button type="button" class="btn btn-sm btn-success ms-2 onekite-join-outing" data-oid="${oidPlain}" title="S'ajouter" aria-label="S'ajouter">+</button>`
|
|
1824
1828
|
: '';
|
|
1825
|
-
const leaveBtn = (
|
|
1829
|
+
const leaveBtn = (canJoinHere && p.isParticipant)
|
|
1826
1830
|
? `<button type="button" class="btn btn-sm btn-danger ms-2 onekite-leave-outing" data-oid="${oidPlain}" title="Se retirer" aria-label="Se retirer">−</button>`
|
|
1827
1831
|
: '';
|
|
1828
1832
|
const participantsHtml = `<div class="mb-2" id="onekite-participants-outing"><strong>Participants</strong>${joinBtn}${leaveBtn}<br>` +
|
|
Binary file
|